From c537525a7e26788713a6c621ea6c696e412e1cca Mon Sep 17 00:00:00 2001 From: crunk Date: Sun, 13 Feb 2022 21:49:07 +0100 Subject: [PATCH] a database upgrade that makes everything very unstable --- verse/app.py | 7 +-- verse/deploydb.py | 2 +- verse/distribusimodel.py | 20 +++++++++ verse/forms/uploadform.py | 33 ++++++++------ verse/start.py | 45 ++++++++++++++----- verse/statuspengguna/helper.py | 9 ++-- verse/statuspengguna/loginuser.py | 24 ++++++++++ .../templates/distribusiworkflow/upload.html | 21 +++++++++ verse/usermodel.py | 3 +- 9 files changed, 130 insertions(+), 34 deletions(-) create mode 100644 verse/distribusimodel.py create mode 100644 verse/statuspengguna/loginuser.py diff --git a/verse/app.py b/verse/app.py index 7ba576c..fcc01f4 100644 --- a/verse/app.py +++ b/verse/app.py @@ -1,3 +1,4 @@ +import os from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_bcrypt import Bcrypt @@ -17,9 +18,9 @@ def create_app(): APP = Flask(__name__, static_folder="static") 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['MAX_CONTENT_LENGTH'] = 150 * 1024 * 1024 + #APP.config['MAX_CONTENT_LENGTH'] = 150 * 1024 * 1024 login_manager.session_protection = "strong" login_manager.login_view = "index" @@ -27,7 +28,7 @@ def create_app(): csrf = CSRFProtect() - APP.config['SECRET_KEY'] = 'ty4425hk54a21eee5719b9s9df7sdfklx' + APP.config['SECRET_KEY'] = os.urandom(24) APP.config['UPLOAD_FOLDER'] = 'tmpupload' csrf.init_app(APP) diff --git a/verse/deploydb.py b/verse/deploydb.py index fb49da9..d7d6439 100644 --- a/verse/deploydb.py +++ b/verse/deploydb.py @@ -5,7 +5,7 @@ def deploy(): # This model is required for flask_migrate to make the table from usermodel import User # noqa: F401 - + from distribusimodel import Distribusis # noqa: F401 app = create_app() app.app_context().push() db.create_all() diff --git a/verse/distribusimodel.py b/verse/distribusimodel.py new file mode 100644 index 0000000..79cfe38 --- /dev/null +++ b/verse/distribusimodel.py @@ -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 "" % self.distribusiname diff --git a/verse/forms/uploadform.py b/verse/forms/uploadform.py index 767d20a..b6bc14f 100644 --- a/verse/forms/uploadform.py +++ b/verse/forms/uploadform.py @@ -1,36 +1,41 @@ 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.validators import Length, ValidationError +from wtforms.validators import Length, NumberRange from wtforms import ( SubmitField, StringField, + IntegerField, ) class UploadForm(FlaskForm): """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( "Name of your website:", 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( "Upload your zip file with content here:", validators=[ FileAllowed(["zip"], "Zip archives only!"), - FileSizeLimit(max_size_in_mb=100), + FileRequired(), + FileSize( + max_size=104857600, + message="Zipfile size must be smaller than 100MB", + ), ], ) diff --git a/verse/start.py b/verse/start.py index 9d8e77d..48e44dc 100644 --- a/verse/start.py +++ b/verse/start.py @@ -35,6 +35,7 @@ from flask_wtf.csrf import CSRFError from app import create_app, db, login_manager from usermodel import User +from distribusimodel import Distribusis # Forms! from forms.loginform import LoginForm @@ -61,10 +62,13 @@ def session_handler(): @APP.route("/") def index(): - users = User.query.filter(User.distribusiname.isnot(None)).all() + distribusis = Distribusis.query.filter( + Distribusis.distribusiname.isnot(None) + ).all() distribusies = {} - for user in users: - distribusies.update({user.email: user.distribusiname}) + for distribusi in distribusis: + user = User.query.filter_by(id=distribusi.userid).first() + distribusies.update({user.email: distribusi.distribusiname}) return render_template("index.html", distribusies=distribusies) @@ -151,10 +155,12 @@ def distribusi(): themeform = ThemeForm() files_uploaded = AreFilesUploaded() user = User.query.filter_by(email=current_user.email).first() + distribusi = Distribusis.query.filter_by(userid=user.id).first() if distribusiform.validate_on_submit(): - zipfilename = "{}.zip".format(user.distribusiname) - userfolder = os.path.join("stash", user.distribusiname) + zipfilename = "{}.zip".format(distribusi.distribusiname) + userfolder = os.path.join("stash", distribusi.distribusiname) unzipfile = os.path.join(userfolder, zipfilename) + print(unzipfile) if os.path.exists(unzipfile): with zipfile.ZipFile(unzipfile, "r") as zip_ref: # To do, replace extractall with inspection and extract @@ -190,16 +196,34 @@ def upload(): files_uploaded = False if uploadform.validate_on_submit(): 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.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): os.mkdir(newuserfolder) + copyzipfile = os.path.join(APP.config["UPLOAD_FOLDER"], zipfilename) shutil.copy(copyzipfile, newuserfolder) os.remove(os.path.join(APP.config["UPLOAD_FOLDER"], zipfilename)) @@ -223,7 +247,8 @@ def theme(): files_uploaded = AreFilesUploaded() if themeform.validate_on_submit(): 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( "themes", "{}.css".format(themeform.theme.data), diff --git a/verse/statuspengguna/helper.py b/verse/statuspengguna/helper.py index 6fc03a0..be5b0bc 100644 --- a/verse/statuspengguna/helper.py +++ b/verse/statuspengguna/helper.py @@ -1,14 +1,15 @@ import os from flask_login import current_user from usermodel import User - +from distribusimodel import Distribusis def AreFilesUploaded(): user = User.query.filter_by(email=current_user.email).first() - if user.distribusiname is None: - print("distribusi name is empty") + distribusi = Distribusis.query.filter_by(userid=user.id).first() + if distribusi is None: + print("distribusi is empty") return False - userfolder = os.path.join("stash", user.distribusiname) + userfolder = os.path.join("stash", distribusi.distribusiname) if os.path.exists(userfolder): print("folder found, files are uploaded") return True diff --git a/verse/statuspengguna/loginuser.py b/verse/statuspengguna/loginuser.py new file mode 100644 index 0000000..3858b5e --- /dev/null +++ b/verse/statuspengguna/loginuser.py @@ -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 diff --git a/verse/templates/distribusiworkflow/upload.html b/verse/templates/distribusiworkflow/upload.html index 132997f..2eab968 100644 --- a/verse/templates/distribusiworkflow/upload.html +++ b/verse/templates/distribusiworkflow/upload.html @@ -10,6 +10,27 @@
{{ message }}
{% endfor %} +
+ {{ uploadform.academicyear.label }} + {{ uploadform.academicyear }} + {% for message in uploadform.academicyear.errors %} +
{{ message }}
+ {% endfor %} +
+
+ {{ uploadform.term.label }} + {{ uploadform.term }} + {% for message in uploadform.term.errors %} +
{{ message }}
+ {% endfor %} +
+
+ {{ uploadform.tags.label }} + {{ uploadform.tags }} + {% for message in uploadform.tags.errors %} +
{{ message }}
+ {% endfor %} +
{{ uploadform.zipfile.label }} {{ uploadform.zipfile }} diff --git a/verse/usermodel.py b/verse/usermodel.py index 158c2c3..d2183cc 100644 --- a/verse/usermodel.py +++ b/verse/usermodel.py @@ -8,10 +8,9 @@ class User(UserMixin, db.Model): __tablename__ = "users" 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) password = db.Column(db.String(300), nullable=False, unique=False) - visible = db.Column(db.Boolean, server_default=u'false') + def __repr__(self): return "" % self.email