a database upgrade that makes everything very unstable

This commit is contained in:
crunk 2022-02-13 21:49:07 +01:00
parent a32238e128
commit c537525a7e
9 changed files with 130 additions and 34 deletions

View File

@ -1,3 +1,4 @@
import os
from flask import Flask from flask import Flask
from flask_sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt from flask_bcrypt import Bcrypt
@ -17,9 +18,9 @@ def create_app():
APP = Flask(__name__, static_folder="static") APP = Flask(__name__, static_folder="static")
APP.secret_key = 'secret-key' APP.secret_key = 'secret-key'
APP.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///data/login.db" APP.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///data/distribusiverse.db"
APP.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True APP.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
APP.config['MAX_CONTENT_LENGTH'] = 150 * 1024 * 1024 #APP.config['MAX_CONTENT_LENGTH'] = 150 * 1024 * 1024
login_manager.session_protection = "strong" login_manager.session_protection = "strong"
login_manager.login_view = "index" login_manager.login_view = "index"
@ -27,7 +28,7 @@ def create_app():
csrf = CSRFProtect() csrf = CSRFProtect()
APP.config['SECRET_KEY'] = 'ty4425hk54a21eee5719b9s9df7sdfklx' APP.config['SECRET_KEY'] = os.urandom(24)
APP.config['UPLOAD_FOLDER'] = 'tmpupload' APP.config['UPLOAD_FOLDER'] = 'tmpupload'
csrf.init_app(APP) csrf.init_app(APP)

View File

@ -5,7 +5,7 @@ def deploy():
# This model is required for flask_migrate to make the table # This model is required for flask_migrate to make the table
from usermodel import User # noqa: F401 from usermodel import User # noqa: F401
from distribusimodel import Distribusis # noqa: F401
app = create_app() app = create_app()
app.app_context().push() app.app_context().push()
db.create_all() db.create_all()

20
verse/distribusimodel.py Normal file
View File

@ -0,0 +1,20 @@
from app import db
class Distribusis(db.Model):
"""distribusi model class for a single distribusi in distribusi-verse"""
__tablename__ = "distribusis"
id = db.Column(db.Integer, primary_key=True)
distribusiname = db.Column(db.String(300), nullable=True, unique=True)
userid = db.Column(db.Integer, db.ForeignKey("users.id"))
term = db.Column(db.Integer, nullable=False, unique=False)
# Academic year eg:2020-2021, so no need for a Datetime object
year = db.Column(db.String(9), nullable=True, unique=False)
tags = db.Column(db.String(500), nullable=True, unique=False)
visible = db.Column(db.Boolean, server_default="false")
def __repr__(self):
return "<Distribusi %r>" % self.distribusiname

View File

@ -1,36 +1,41 @@
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from flask_wtf.file import FileField, FileAllowed from flask_wtf.file import FileField, FileAllowed, FileRequired, FileSize
from wtforms import validators from wtforms import validators
from wtforms.validators import Length, ValidationError from wtforms.validators import Length, NumberRange
from wtforms import ( from wtforms import (
SubmitField, SubmitField,
StringField, StringField,
IntegerField,
) )
class UploadForm(FlaskForm): class UploadForm(FlaskForm):
"""File upload class for a new site in distribusi-verse""" """File upload class for a new site in distribusi-verse"""
def FileSizeLimit(max_size_in_mb):
max_bytes = max_size_in_mb * 1024 * 1024
def file_length_check(form, field):
if len(field.data.read()) > max_bytes:
raise ValidationError(
"File size must be less than {}MB".format(max_size_in_mb)
)
return file_length_check
sitename = StringField( sitename = StringField(
"Name of your website:", "Name of your website:",
validators=[validators.InputRequired(), Length(2, 100)], validators=[validators.InputRequired(), Length(2, 100)],
) )
academicyear = StringField(
"Academic year:",
validators=[validators.InputRequired(), Length(9, 10)],
)
term = IntegerField(
"Term:", [validators.InputRequired(), NumberRange(min=1, max=4)]
)
tags = StringField(
"Add search tags, comma-separated:",
validators=[validators.InputRequired(), Length(2, 500)],
)
zipfile = FileField( zipfile = FileField(
"Upload your zip file with content here:", "Upload your zip file with content here:",
validators=[ validators=[
FileAllowed(["zip"], "Zip archives only!"), FileAllowed(["zip"], "Zip archives only!"),
FileSizeLimit(max_size_in_mb=100), FileRequired(),
FileSize(
max_size=104857600,
message="Zipfile size must be smaller than 100MB",
),
], ],
) )

View File

@ -35,6 +35,7 @@ from flask_wtf.csrf import CSRFError
from app import create_app, db, login_manager from app import create_app, db, login_manager
from usermodel import User from usermodel import User
from distribusimodel import Distribusis
# Forms! # Forms!
from forms.loginform import LoginForm from forms.loginform import LoginForm
@ -61,10 +62,13 @@ def session_handler():
@APP.route("/") @APP.route("/")
def index(): def index():
users = User.query.filter(User.distribusiname.isnot(None)).all() distribusis = Distribusis.query.filter(
Distribusis.distribusiname.isnot(None)
).all()
distribusies = {} distribusies = {}
for user in users: for distribusi in distribusis:
distribusies.update({user.email: user.distribusiname}) user = User.query.filter_by(id=distribusi.userid).first()
distribusies.update({user.email: distribusi.distribusiname})
return render_template("index.html", distribusies=distribusies) return render_template("index.html", distribusies=distribusies)
@ -151,10 +155,12 @@ def distribusi():
themeform = ThemeForm() themeform = ThemeForm()
files_uploaded = AreFilesUploaded() files_uploaded = AreFilesUploaded()
user = User.query.filter_by(email=current_user.email).first() user = User.query.filter_by(email=current_user.email).first()
distribusi = Distribusis.query.filter_by(userid=user.id).first()
if distribusiform.validate_on_submit(): if distribusiform.validate_on_submit():
zipfilename = "{}.zip".format(user.distribusiname) zipfilename = "{}.zip".format(distribusi.distribusiname)
userfolder = os.path.join("stash", user.distribusiname) userfolder = os.path.join("stash", distribusi.distribusiname)
unzipfile = os.path.join(userfolder, zipfilename) unzipfile = os.path.join(userfolder, zipfilename)
print(unzipfile)
if os.path.exists(unzipfile): if os.path.exists(unzipfile):
with zipfile.ZipFile(unzipfile, "r") as zip_ref: with zipfile.ZipFile(unzipfile, "r") as zip_ref:
# To do, replace extractall with inspection and extract # To do, replace extractall with inspection and extract
@ -190,16 +196,34 @@ def upload():
files_uploaded = False files_uploaded = False
if uploadform.validate_on_submit(): if uploadform.validate_on_submit():
user = User.query.filter_by(email=current_user.email).first() user = User.query.filter_by(email=current_user.email).first()
user.distribusiname = uploadform.sitename.data
db.session.commit()
zipfilename = "{}.zip".format(user.distribusiname) try:
newdistribusi = Distribusis(
distribusiname=uploadform.sitename.data,
userid=user.id,
year=uploadform.academicyear.data,
term=uploadform.term.data,
tags=uploadform.tags.data,
)
db.session.add(newdistribusi)
db.session.commit()
except InvalidRequestError:
db.session.rollback()
uploadform.sitename.errors.append("Something went wrong!")
flash("Something went wrong!", "danger")
except IntegrityError:
db.session.rollback()
uploadform.sitename.errors.append("distribusi name already exists!")
flash("distribusi name already exists!", "warning")
zipfilename = "{}.zip".format(newdistribusi.distribusiname)
zipfile = uploadform.zipfile.data zipfile = uploadform.zipfile.data
zipfile.save(os.path.join(APP.config["UPLOAD_FOLDER"], zipfilename)) zipfile.save(os.path.join(APP.config["UPLOAD_FOLDER"], zipfilename))
newuserfolder = os.path.join("stash", user.distribusiname) newuserfolder = os.path.join("stash", newdistribusi.distribusiname)
if not os.path.exists(newuserfolder): if not os.path.exists(newuserfolder):
os.mkdir(newuserfolder) os.mkdir(newuserfolder)
copyzipfile = os.path.join(APP.config["UPLOAD_FOLDER"], zipfilename) copyzipfile = os.path.join(APP.config["UPLOAD_FOLDER"], zipfilename)
shutil.copy(copyzipfile, newuserfolder) shutil.copy(copyzipfile, newuserfolder)
os.remove(os.path.join(APP.config["UPLOAD_FOLDER"], zipfilename)) os.remove(os.path.join(APP.config["UPLOAD_FOLDER"], zipfilename))
@ -223,7 +247,8 @@ def theme():
files_uploaded = AreFilesUploaded() files_uploaded = AreFilesUploaded()
if themeform.validate_on_submit(): if themeform.validate_on_submit():
user = User.query.filter_by(email=current_user.email).first() user = User.query.filter_by(email=current_user.email).first()
newuserfolder = os.path.join("stash", user.distribusiname) distribusi = Distribusis.query.filter_by(userid=user.id).first()
newuserfolder = os.path.join("stash", distribusi.distribusiname)
copycssfile = os.path.join( copycssfile = os.path.join(
"themes", "themes",
"{}.css".format(themeform.theme.data), "{}.css".format(themeform.theme.data),

View File

@ -1,14 +1,15 @@
import os import os
from flask_login import current_user from flask_login import current_user
from usermodel import User from usermodel import User
from distribusimodel import Distribusis
def AreFilesUploaded(): def AreFilesUploaded():
user = User.query.filter_by(email=current_user.email).first() user = User.query.filter_by(email=current_user.email).first()
if user.distribusiname is None: distribusi = Distribusis.query.filter_by(userid=user.id).first()
print("distribusi name is empty") if distribusi is None:
print("distribusi is empty")
return False return False
userfolder = os.path.join("stash", user.distribusiname) userfolder = os.path.join("stash", distribusi.distribusiname)
if os.path.exists(userfolder): if os.path.exists(userfolder):
print("folder found, files are uploaded") print("folder found, files are uploaded")
return True return True

View File

@ -0,0 +1,24 @@
import os
from flask_login import current_user
from usermodel import User
from forms.loginform import LoginForm
def LoginUser():
loginform = LoginForm()
if loginform.validate_on_submit():
try:
user = User.query.filter_by(email=loginform.email.data).first()
if user is None:
loginform.password.errors.append("Invalid email or password!")
return render_template("login.html", loginform=loginform)
if check_password_hash(user.password, loginform.password.data):
login_user(user)
flash("Logged in successfully.", "success")
else:
flash("Invalid email or password!", "danger")
loginform.password.errors.append("Invalid email or password!")
return loginform
except Exception as e:
flash(e, "danger")
return loginform

View File

@ -10,6 +10,27 @@
<div class="error">{{ message }}</div> <div class="error">{{ message }}</div>
{% endfor %} {% endfor %}
</fieldset> </fieldset>
<fieldset class="required">
{{ uploadform.academicyear.label }}
{{ uploadform.academicyear }}
{% for message in uploadform.academicyear.errors %}
<div class="error">{{ message }}</div>
{% endfor %}
</fieldset>
<fieldset class="required">
{{ uploadform.term.label }}
{{ uploadform.term }}
{% for message in uploadform.term.errors %}
<div class="error">{{ message }}</div>
{% endfor %}
</fieldset>
<fieldset class="required tags">
{{ uploadform.tags.label }}
{{ uploadform.tags }}
{% for message in uploadform.tags.errors %}
<div class="error">{{ message }}</div>
{% endfor %}
</fieldset>
<fieldset class="required"> <fieldset class="required">
{{ uploadform.zipfile.label }} {{ uploadform.zipfile.label }}
{{ uploadform.zipfile }} {{ uploadform.zipfile }}

View File

@ -8,10 +8,9 @@ class User(UserMixin, db.Model):
__tablename__ = "users" __tablename__ = "users"
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
distribusiname = db.Column(db.String(300), unique=True, nullable=True)
email = db.Column(db.String(150), unique=True, nullable=False) email = db.Column(db.String(150), unique=True, nullable=False)
password = db.Column(db.String(300), nullable=False, unique=False) password = db.Column(db.String(300), nullable=False, unique=False)
visible = db.Column(db.Boolean, server_default=u'false')
def __repr__(self): def __repr__(self):
return "<User %r>" % self.email return "<User %r>" % self.email