main #12
@ -1,25 +1,49 @@
|
|||||||
[tool.black]
|
[tool.ruff]
|
||||||
line-length = 79
|
line-length = 79
|
||||||
target-version = ['py311']
|
target-version = "py311"
|
||||||
include = '\.pyi?$'
|
#include = '\.pyi?$'
|
||||||
exclude = '''
|
exclude = [
|
||||||
/(
|
".bzr",
|
||||||
\.eggs
|
".direnv",
|
||||||
| \.git
|
".eggs",
|
||||||
| \.hg
|
".git",
|
||||||
| \.mypy_cache
|
".git-rewrite",
|
||||||
| \.tox
|
".hg",
|
||||||
| \.venv
|
".ipynb_checkpoints",
|
||||||
| _build
|
".mypy_cache",
|
||||||
| buck-out
|
".nox",
|
||||||
| build
|
".pants.d",
|
||||||
| dist
|
".pyenv",
|
||||||
|
".pytest_cache",
|
||||||
# The following are specific to Black, you probably don't want those.
|
".pytype",
|
||||||
| blib2to3
|
".ruff_cache",
|
||||||
| tests/data
|
".svn",
|
||||||
| profiling
|
".tox",
|
||||||
)/
|
".venv",
|
||||||
'''
|
".vscode",
|
||||||
|
"__pypackages__",
|
||||||
|
"_build",
|
||||||
|
"buck-out",
|
||||||
|
"build",
|
||||||
|
"dist",
|
||||||
|
"node_modules",
|
||||||
|
"site-packages",
|
||||||
|
"venv",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.ruff.lint]
|
||||||
|
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
|
||||||
|
select = ["E4", "E7", "E9", "F"]
|
||||||
|
ignore = []
|
||||||
|
# Allow fix for all enabled rules (when `--fix`) is provided.
|
||||||
|
fixable = ["ALL"]
|
||||||
|
unfixable = []
|
||||||
|
# Allow unused variables when underscore-prefixed.
|
||||||
|
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
|
||||||
|
|
||||||
|
[tool.ruff.format]
|
||||||
|
quote-style = "double"
|
||||||
|
indent-style = "tab"
|
||||||
|
docstring-code-format = true
|
||||||
|
line-ending = "auto"
|
||||||
|
skip-magic-trailing-comma = false
|
||||||
|
@ -3,10 +3,10 @@ import shutil
|
|||||||
|
|
||||||
from flask import render_template
|
from flask import render_template
|
||||||
from sqlalchemy.exc import (
|
from sqlalchemy.exc import (
|
||||||
DatabaseError,
|
DatabaseError,
|
||||||
DataError,
|
DataError,
|
||||||
InterfaceError,
|
InterfaceError,
|
||||||
InvalidRequestError,
|
InvalidRequestError,
|
||||||
)
|
)
|
||||||
|
|
||||||
from app import db
|
from app import db
|
||||||
@ -18,88 +18,88 @@ from models.user_model import User
|
|||||||
|
|
||||||
|
|
||||||
def AdminPage():
|
def AdminPage():
|
||||||
adminuserform = AddUsersToForm(AdminUserForm())
|
adminuserform = AddUsersToForm(AdminUserForm())
|
||||||
admindistribusiform = AddDistribusisToForm(AdminDistribusiForm())
|
admindistribusiform = AddDistribusisToForm(AdminDistribusiForm())
|
||||||
if admindistribusiform.validate_on_submit():
|
if admindistribusiform.validate_on_submit():
|
||||||
DeleteDistribusis(admindistribusiform)
|
DeleteDistribusis(admindistribusiform)
|
||||||
|
|
||||||
if adminuserform.validate_on_submit():
|
if adminuserform.validate_on_submit():
|
||||||
if adminuserform.delete.data:
|
if adminuserform.delete.data:
|
||||||
DeleteUsers(adminuserform)
|
DeleteUsers(adminuserform)
|
||||||
|
|
||||||
template = render_template(
|
template = render_template(
|
||||||
"admin.html",
|
"admin.html",
|
||||||
adminuserform=adminuserform,
|
adminuserform=adminuserform,
|
||||||
admindistribusiform=admindistribusiform,
|
admindistribusiform=admindistribusiform,
|
||||||
)
|
)
|
||||||
return template
|
return template
|
||||||
|
|
||||||
|
|
||||||
def DeleteUsers(adminuserform):
|
def DeleteUsers(adminuserform):
|
||||||
for userform in adminuserform:
|
for userform in adminuserform:
|
||||||
if "user" in userform.id:
|
if "user" in userform.id:
|
||||||
if userform.data:
|
if userform.data:
|
||||||
useremail = userform.label.text
|
useremail = userform.label.text
|
||||||
user = User.query.filter_by(email=useremail).first()
|
user = User.query.filter_by(email=useremail).first()
|
||||||
DeleteUserDistribusis(user)
|
DeleteUserDistribusis(user)
|
||||||
DeleteUserFromDb(user)
|
DeleteUserFromDb(user)
|
||||||
userform.errors.append(f"User {useremail} deleted!")
|
userform.errors.append(f"User {useremail} deleted!")
|
||||||
|
|
||||||
|
|
||||||
def DeleteUserFromDb(user):
|
def DeleteUserFromDb(user):
|
||||||
try:
|
try:
|
||||||
db.session.delete(user)
|
db.session.delete(user)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
except (InvalidRequestError, DataError, InterfaceError, DatabaseError):
|
except (InvalidRequestError, DataError, InterfaceError, DatabaseError):
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
|
|
||||||
|
|
||||||
def DeleteUserDistribusis(user):
|
def DeleteUserDistribusis(user):
|
||||||
distribusis = DistribusisInfo.getuserdistribusis(user.email)
|
distribusis = DistribusisInfo.getuserdistribusis(user.email)
|
||||||
for distribusi in distribusis:
|
for distribusi in distribusis:
|
||||||
DeleteDistribusiFiles(distribusi.distribusiname)
|
DeleteDistribusiFiles(distribusi.distribusiname)
|
||||||
DeleteDistribusiFromDb(distribusi)
|
DeleteDistribusiFromDb(distribusi)
|
||||||
|
|
||||||
|
|
||||||
def DeleteDistribusis(admindistribusiform):
|
def DeleteDistribusis(admindistribusiform):
|
||||||
for distribusiform in admindistribusiform:
|
for distribusiform in admindistribusiform:
|
||||||
if "distribusi" in distribusiform.id:
|
if "distribusi" in distribusiform.id:
|
||||||
if distribusiform.data:
|
if distribusiform.data:
|
||||||
distribusiname = distribusiform.label.text
|
distribusiname = distribusiform.label.text
|
||||||
distribusi = Distribusis.query.filter_by(
|
distribusi = Distribusis.query.filter_by(
|
||||||
distribusiname=distribusiname
|
distribusiname=distribusiname
|
||||||
).first()
|
).first()
|
||||||
DeleteDistribusiFromDb(distribusi)
|
DeleteDistribusiFromDb(distribusi)
|
||||||
DeleteDistribusiFiles(distribusiname)
|
DeleteDistribusiFiles(distribusiname)
|
||||||
distribusiform.errors.append("Deleted distribusi")
|
distribusiform.errors.append("Deleted distribusi")
|
||||||
|
|
||||||
|
|
||||||
def DeleteDistribusiFromDb(distribusi):
|
def DeleteDistribusiFromDb(distribusi):
|
||||||
try:
|
try:
|
||||||
db.session.delete(distribusi)
|
db.session.delete(distribusi)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
except (InvalidRequestError, DataError, InterfaceError, DatabaseError):
|
except (InvalidRequestError, DataError, InterfaceError, DatabaseError):
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
|
|
||||||
|
|
||||||
def DeleteDistribusiFiles(distribusiname):
|
def DeleteDistribusiFiles(distribusiname):
|
||||||
userfolder = os.path.join("stash", distribusiname)
|
userfolder = os.path.join("stash", distribusiname)
|
||||||
if os.path.exists(userfolder):
|
if os.path.exists(userfolder):
|
||||||
shutil.rmtree(userfolder)
|
shutil.rmtree(userfolder)
|
||||||
cssfolder = os.path.join("themes/userthemes", distribusiname)
|
cssfolder = os.path.join("themes/userthemes", distribusiname)
|
||||||
if os.path.exists(cssfolder):
|
if os.path.exists(cssfolder):
|
||||||
shutil.rmtree(cssfolder)
|
shutil.rmtree(cssfolder)
|
||||||
|
|
||||||
|
|
||||||
def AddDistribusisToForm(admindistribusiform):
|
def AddDistribusisToForm(admindistribusiform):
|
||||||
distribusis = DistribusisInfo.visibledistribusis()
|
distribusis = DistribusisInfo.visibledistribusis()
|
||||||
admindistribusiform = AdminDistribusiForm.distribusi_list_form_builder(
|
admindistribusiform = AdminDistribusiForm.distribusi_list_form_builder(
|
||||||
distribusis
|
distribusis
|
||||||
)
|
)
|
||||||
return admindistribusiform
|
return admindistribusiform
|
||||||
|
|
||||||
|
|
||||||
def AddUsersToForm(adminuserform):
|
def AddUsersToForm(adminuserform):
|
||||||
users = User.query.all()
|
users = User.query.all()
|
||||||
adminuserform = AdminUserForm.user_list_form_builder(users)
|
adminuserform = AdminUserForm.user_list_form_builder(users)
|
||||||
return adminuserform
|
return adminuserform
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from sqlalchemy.exc import (
|
from sqlalchemy.exc import (
|
||||||
DatabaseError,
|
DatabaseError,
|
||||||
DataError,
|
DataError,
|
||||||
InterfaceError,
|
InterfaceError,
|
||||||
InvalidRequestError,
|
InvalidRequestError,
|
||||||
)
|
)
|
||||||
|
|
||||||
from app import create_app, db
|
from app import create_app, db
|
||||||
@ -13,32 +13,32 @@ from models.user_model import User # noqa: F401
|
|||||||
|
|
||||||
|
|
||||||
def admintool():
|
def admintool():
|
||||||
"""Admin CLI tool. To elevate a user to admin"""
|
"""Admin CLI tool. To elevate a user to admin"""
|
||||||
app = create_app()
|
app = create_app()
|
||||||
app.app_context().push()
|
app.app_context().push()
|
||||||
elevateusertoadmin()
|
elevateusertoadmin()
|
||||||
|
|
||||||
|
|
||||||
def elevateusertoadmin():
|
def elevateusertoadmin():
|
||||||
"""To elevates user of first command line argument to admin"""
|
"""To elevates user of first command line argument to admin"""
|
||||||
user = User.query.filter_by(email=sys.argv[1]).first()
|
user = User.query.filter_by(email=sys.argv[1]).first()
|
||||||
print(f"user {user.username} found with email {user.email}")
|
print(f"user {user.username} found with email {user.email}")
|
||||||
try:
|
try:
|
||||||
user.admin = True
|
user.admin = True
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
print(f"Account {user.email} succesfully made into an admin")
|
print(f"Account {user.email} succesfully made into an admin")
|
||||||
except InvalidRequestError:
|
except InvalidRequestError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
print("Something went wrong!")
|
print("Something went wrong!")
|
||||||
except InterfaceError:
|
except InterfaceError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
print("Error connecting to the database")
|
print("Error connecting to the database")
|
||||||
except DataError:
|
except DataError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
print("Invalid Entry")
|
print("Invalid Entry")
|
||||||
except DatabaseError:
|
except DatabaseError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
print("Error connecting to the database")
|
print("Error connecting to the database")
|
||||||
|
|
||||||
|
|
||||||
admintool()
|
admintool()
|
||||||
|
72
verse/app.py
72
verse/app.py
@ -16,56 +16,56 @@ login_manager = LoginManager()
|
|||||||
|
|
||||||
|
|
||||||
def create_app():
|
def create_app():
|
||||||
APP.secret_key = os.urandom(24)
|
APP.secret_key = os.urandom(24)
|
||||||
APP.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///distribusiverse.db"
|
APP.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///distribusiverse.db"
|
||||||
APP.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True
|
APP.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True
|
||||||
|
|
||||||
APP.config["MAX_CONTENT_LENGTH"] = 1024 * 1024 * 1024
|
APP.config["MAX_CONTENT_LENGTH"] = 1024 * 1024 * 1024
|
||||||
APP.config["MAIL_SERVER"] = "mail.autonomic.zone"
|
APP.config["MAIL_SERVER"] = "mail.autonomic.zone"
|
||||||
APP.config["MAIL_PORT"] = 587
|
APP.config["MAIL_PORT"] = 587
|
||||||
APP.config["MAIL_USE_SSL"] = False
|
APP.config["MAIL_USE_SSL"] = False
|
||||||
APP.config["MAIL_USE_TLS"] = True
|
APP.config["MAIL_USE_TLS"] = True
|
||||||
APP.config["MAIL_USERNAME"] = "noreply@vvvvvvaria.org"
|
APP.config["MAIL_USERNAME"] = "noreply@vvvvvvaria.org"
|
||||||
|
|
||||||
login_manager.session_protection = "strong"
|
login_manager.session_protection = "strong"
|
||||||
login_manager.login_view = "index"
|
login_manager.login_view = "index"
|
||||||
login_manager.login_message_category = "info"
|
login_manager.login_message_category = "info"
|
||||||
|
|
||||||
csrf = CSRFProtect()
|
csrf = CSRFProtect()
|
||||||
|
|
||||||
APP.config["SECRET_KEY"] = os.urandom(24)
|
APP.config["SECRET_KEY"] = os.urandom(24)
|
||||||
APP.config["UPLOAD_FOLDER"] = "tmpupload"
|
APP.config["UPLOAD_FOLDER"] = "tmpupload"
|
||||||
APP.config["PUBLIC_THEMES"] = "themes/publicthemes"
|
APP.config["PUBLIC_THEMES"] = "themes/publicthemes"
|
||||||
|
|
||||||
# user settings_file
|
# user settings_file
|
||||||
settings()
|
settings()
|
||||||
|
|
||||||
csrf.init_app(APP)
|
csrf.init_app(APP)
|
||||||
login_manager.init_app(APP)
|
login_manager.init_app(APP)
|
||||||
db.init_app(APP)
|
db.init_app(APP)
|
||||||
migrate.init_app(APP, db, render_as_batch=True)
|
migrate.init_app(APP, db, render_as_batch=True)
|
||||||
bcrypt.init_app(APP)
|
bcrypt.init_app(APP)
|
||||||
|
|
||||||
@APP.context_processor
|
@APP.context_processor
|
||||||
def inject_title():
|
def inject_title():
|
||||||
return dict(title=APP.config["title"])
|
return dict(title=APP.config["title"])
|
||||||
|
|
||||||
return APP
|
return APP
|
||||||
|
|
||||||
|
|
||||||
def settings():
|
def settings():
|
||||||
settings = settings_from_file()
|
settings = settings_from_file()
|
||||||
APP.config.update(settings)
|
APP.config.update(settings)
|
||||||
return APP
|
return APP
|
||||||
|
|
||||||
|
|
||||||
def get_app():
|
def get_app():
|
||||||
return APP
|
return APP
|
||||||
|
|
||||||
|
|
||||||
def settings_from_file():
|
def settings_from_file():
|
||||||
if os.path.isfile("settings_development.toml"):
|
if os.path.isfile("settings_development.toml"):
|
||||||
with open("settings_development.toml", "rb") as settings_file:
|
with open("settings_development.toml", "rb") as settings_file:
|
||||||
return tomllib.load(settings_file)
|
return tomllib.load(settings_file)
|
||||||
with open("settings.toml", "rb") as settings_file:
|
with open("settings.toml", "rb") as settings_file:
|
||||||
return tomllib.load(settings_file)
|
return tomllib.load(settings_file)
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
def deploy():
|
def deploy():
|
||||||
"""Run deployment of database."""
|
"""Run deployment of database."""
|
||||||
from flask_migrate import init, migrate, stamp, upgrade
|
from flask_migrate import init, migrate, stamp, upgrade
|
||||||
|
|
||||||
from app import create_app, db
|
from app import create_app, db
|
||||||
from models.distribusi_model import Distribusis # noqa: F401
|
from models.distribusi_model import Distribusis # noqa: F401
|
||||||
from models.distribusi_file_model import DistribusiFiles # noqa: F401
|
from models.distribusi_file_model import DistribusiFiles # noqa: F401
|
||||||
|
|
||||||
# This model is required for flask_migrate to make the table
|
# This model is required for flask_migrate to make the table
|
||||||
from models.user_model import User # noqa: F401
|
from models.user_model import User # noqa: F401
|
||||||
|
|
||||||
app = create_app()
|
app = create_app()
|
||||||
app.app_context().push()
|
app.app_context().push()
|
||||||
db.create_all()
|
db.create_all()
|
||||||
|
|
||||||
# migrate database to latest revision
|
# migrate database to latest revision
|
||||||
init()
|
init()
|
||||||
stamp()
|
stamp()
|
||||||
migrate()
|
migrate()
|
||||||
upgrade()
|
upgrade()
|
||||||
|
|
||||||
|
|
||||||
deploy()
|
deploy()
|
||||||
|
@ -2,23 +2,31 @@ from flask import Blueprint, render_template, redirect, url_for
|
|||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from models.distribusi_model import Distribusis
|
from models.distribusi_model import Distribusis
|
||||||
from models.distribusi_file_model import DistribusiFiles
|
from models.distribusi_file_model import DistribusiFiles
|
||||||
|
from describer.forms.describe_file_form import DescribeFileForm
|
||||||
|
|
||||||
describer = Blueprint(
|
describer = Blueprint(
|
||||||
"describer",
|
"describer",
|
||||||
__name__,
|
__name__,
|
||||||
template_folder="templates/describe_files",
|
template_folder="templates/describe_files",
|
||||||
static_folder="static",
|
static_folder="static",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@describer.route("/<string:distribusiname>")
|
@describer.route("/<string:distribusiname>")
|
||||||
def describe_distribusi_files(distribusiname):
|
def describe_distribusi_files(distribusiname):
|
||||||
if not current_user.is_authenticated:
|
if not current_user.is_authenticated:
|
||||||
return redirect(url_for("index"))
|
return redirect(url_for("index"))
|
||||||
distribusi = Distribusis.query.filter_by(
|
distribusi = Distribusis.query.filter_by(
|
||||||
distribusiname=distribusiname
|
distribusiname=distribusiname
|
||||||
).first()
|
).first()
|
||||||
distribusi_files = DistribusiFiles.query.filter_by(
|
distribusi_files = DistribusiFiles.query.filter_by(
|
||||||
distribusi=distribusi.id
|
distribusi=distribusi.id
|
||||||
).all()
|
).all()
|
||||||
return render_template("describe.html", distribusi_files=distribusi_files)
|
# distribusi_file_forms = {}
|
||||||
|
# for distribusi_file in distribusi_files:
|
||||||
|
describe_form = DescribeFileForm()
|
||||||
|
return render_template(
|
||||||
|
"describe.html",
|
||||||
|
distribusi_files=distribusi_files,
|
||||||
|
describe_form=describe_form,
|
||||||
|
)
|
||||||
|
@ -4,28 +4,29 @@ from flask_wtf import FlaskForm
|
|||||||
from wtforms import StringField, SubmitField, validators
|
from wtforms import StringField, SubmitField, validators
|
||||||
from wtforms.validators import Length
|
from wtforms.validators import Length
|
||||||
|
|
||||||
class DescribeFileForm(FlaskForm):
|
|
||||||
"""DescribeFileForm selection form."""
|
|
||||||
|
|
||||||
alttext = StringField(
|
class DescribeFileForm(FlaskForm):
|
||||||
"Alt-text for this file:",
|
"""DescribeFileForm selection form."""
|
||||||
validators=[
|
|
||||||
validators.InputRequired(),
|
alttext = StringField(
|
||||||
Length(3, 255),
|
"Alt-text for this file:",
|
||||||
],
|
validators=[
|
||||||
)
|
validators.InputRequired(),
|
||||||
searchtags = StringField(
|
Length(3, 255),
|
||||||
"Add search tags, seperated by commas. No need for the '#' sign:",
|
],
|
||||||
validators=[
|
)
|
||||||
validators.InputRequired(),
|
searchtags = StringField(
|
||||||
Length(3, 500),
|
"Add search tags, seperated by commas. No need for the '#' sign:",
|
||||||
],
|
validators=[
|
||||||
)
|
validators.InputRequired(),
|
||||||
description = StringField(
|
Length(3, 500),
|
||||||
"Description of this file:",
|
],
|
||||||
validators=[
|
)
|
||||||
validators.InputRequired(),
|
description = StringField(
|
||||||
Length(3, 4096),
|
"Description of this file:",
|
||||||
],
|
validators=[
|
||||||
)
|
validators.InputRequired(),
|
||||||
save = SubmitField("Save")
|
Length(3, 4096),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
save = SubmitField("Save")
|
||||||
|
@ -10,38 +10,38 @@ from distribusikan.themeselector import ThemeSelector
|
|||||||
from distribusikan.uploadpage import UploadPage
|
from distribusikan.uploadpage import UploadPage
|
||||||
|
|
||||||
distribusikan = Blueprint(
|
distribusikan = Blueprint(
|
||||||
"distribusikan",
|
"distribusikan",
|
||||||
__name__,
|
__name__,
|
||||||
template_folder="templates/distribusikan",
|
template_folder="templates/distribusikan",
|
||||||
static_folder="static",
|
static_folder="static",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@distribusikan.route("/distribusi", methods=["GET", "POST"])
|
@distribusikan.route("/distribusi", methods=["GET", "POST"])
|
||||||
@login_required
|
@login_required
|
||||||
def distribusi():
|
def distribusi():
|
||||||
return DistribusiWorkflow()
|
return DistribusiWorkflow()
|
||||||
|
|
||||||
|
|
||||||
@distribusikan.route("/upload", methods=["POST"])
|
@distribusikan.route("/upload", methods=["POST"])
|
||||||
@login_required
|
@login_required
|
||||||
def upload():
|
def upload():
|
||||||
return UploadPage()
|
return UploadPage()
|
||||||
|
|
||||||
|
|
||||||
@distribusikan.route("/theme", methods=["GET", "POST"])
|
@distribusikan.route("/theme", methods=["GET", "POST"])
|
||||||
@login_required
|
@login_required
|
||||||
def theme():
|
def theme():
|
||||||
return ThemeSelector()
|
return ThemeSelector()
|
||||||
|
|
||||||
|
|
||||||
@distribusikan.route("/editor", methods=["GET", "POST"])
|
@distribusikan.route("/editor", methods=["GET", "POST"])
|
||||||
@login_required
|
@login_required
|
||||||
def editor():
|
def editor():
|
||||||
return Editor()
|
return Editor()
|
||||||
|
|
||||||
|
|
||||||
@distribusikan.route("/selector", methods=["GET", "POST"])
|
@distribusikan.route("/selector", methods=["GET", "POST"])
|
||||||
@login_required
|
@login_required
|
||||||
def selector():
|
def selector():
|
||||||
return DistribusiSelector()
|
return DistribusiSelector()
|
||||||
|
@ -4,10 +4,10 @@ import shutil
|
|||||||
from flask import flash, render_template, redirect, url_for
|
from flask import flash, render_template, redirect, url_for
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from sqlalchemy.exc import (
|
from sqlalchemy.exc import (
|
||||||
DatabaseError,
|
DatabaseError,
|
||||||
DataError,
|
DataError,
|
||||||
InterfaceError,
|
InterfaceError,
|
||||||
InvalidRequestError,
|
InvalidRequestError,
|
||||||
)
|
)
|
||||||
|
|
||||||
from app import db
|
from app import db
|
||||||
@ -25,148 +25,148 @@ from statuspengguna.helper import UserHelper
|
|||||||
|
|
||||||
|
|
||||||
def DistribusiSelector():
|
def DistribusiSelector():
|
||||||
uploadform = UploadForm()
|
uploadform = UploadForm()
|
||||||
selectorform = SelectorForm()
|
selectorform = SelectorForm()
|
||||||
selectorform.distribusis.choices = DistribusisInfo.userdistribusinames()
|
selectorform.distribusis.choices = DistribusisInfo.userdistribusinames()
|
||||||
current_distribusi = UserHelper.current_distribusi()
|
current_distribusi = UserHelper.current_distribusi()
|
||||||
if selectorform.validate_on_submit():
|
if selectorform.validate_on_submit():
|
||||||
if selectorform.new.data:
|
if selectorform.new.data:
|
||||||
SelectNewDistribusi()
|
SelectNewDistribusi()
|
||||||
if selectorform.describe.data:
|
if selectorform.describe.data:
|
||||||
return SelectDescribeDistribusi(selectorform.distribusis.data)
|
return SelectDescribeDistribusi(selectorform.distribusis.data)
|
||||||
if selectorform.delete.data:
|
if selectorform.delete.data:
|
||||||
selectorform = DeleteDistribusi(selectorform.distribusis.data)
|
selectorform = DeleteDistribusi(selectorform.distribusis.data)
|
||||||
selectorform.distribusis.choices = (
|
selectorform.distribusis.choices = (
|
||||||
DistribusisInfo.userdistribusinames()
|
DistribusisInfo.userdistribusinames()
|
||||||
)
|
)
|
||||||
if selectorform.update.data:
|
if selectorform.update.data:
|
||||||
SelectUpdateDistribusi(selectorform.distribusis.data)
|
SelectUpdateDistribusi(selectorform.distribusis.data)
|
||||||
current_distribusi = UserHelper.current_distribusi()
|
current_distribusi = UserHelper.current_distribusi()
|
||||||
uploadform = AutoFillInUploadForm(uploadform, current_distribusi)
|
uploadform = AutoFillInUploadForm(uploadform, current_distribusi)
|
||||||
|
|
||||||
return RenderDistribusiTemplate(
|
return RenderDistribusiTemplate(
|
||||||
selectorform, uploadform, current_distribusi
|
selectorform, uploadform, current_distribusi
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def AutoFillInUploadForm(uploadform, current_distribusi):
|
def AutoFillInUploadForm(uploadform, current_distribusi):
|
||||||
distribusi = Distribusis.query.filter_by(
|
distribusi = Distribusis.query.filter_by(
|
||||||
distribusiname=current_distribusi
|
distribusiname=current_distribusi
|
||||||
).first()
|
).first()
|
||||||
uploadform.sitename.data = distribusi.distribusiname
|
uploadform.sitename.data = distribusi.distribusiname
|
||||||
uploadform.sitename.render_kw = {"readonly": True}
|
uploadform.sitename.render_kw = {"readonly": True}
|
||||||
uploadform.category.data = distribusi.category
|
uploadform.category.data = distribusi.category
|
||||||
uploadform.year.data = distribusi.year
|
uploadform.year.data = distribusi.year
|
||||||
uploadform.tags.data = distribusi.tags
|
uploadform.tags.data = distribusi.tags
|
||||||
return uploadform
|
return uploadform
|
||||||
|
|
||||||
|
|
||||||
def SelectNewDistribusi():
|
def SelectNewDistribusi():
|
||||||
print("make a new distribusi")
|
print("make a new distribusi")
|
||||||
SelectCurrentDistribusi("new")
|
SelectCurrentDistribusi("new")
|
||||||
|
|
||||||
|
|
||||||
def SelectDescribeDistribusi(distribusiname):
|
def SelectDescribeDistribusi(distribusiname):
|
||||||
return redirect(
|
return redirect(
|
||||||
url_for(
|
url_for(
|
||||||
"describer.describe_distribusi_files",
|
"describer.describe_distribusi_files",
|
||||||
distribusiname=distribusiname,
|
distribusiname=distribusiname,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def SelectUpdateDistribusi(distribusiname):
|
def SelectUpdateDistribusi(distribusiname):
|
||||||
print(f"Update this distribusi {distribusiname}")
|
print(f"Update this distribusi {distribusiname}")
|
||||||
SelectCurrentDistribusi(distribusiname)
|
SelectCurrentDistribusi(distribusiname)
|
||||||
|
|
||||||
|
|
||||||
def DeleteDistribusi(distribusiname):
|
def DeleteDistribusi(distribusiname):
|
||||||
print(f"delete this distribusi {distribusiname}")
|
print(f"delete this distribusi {distribusiname}")
|
||||||
selectorform = SelectorForm()
|
selectorform = SelectorForm()
|
||||||
try:
|
try:
|
||||||
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(
|
distribusi = Distribusis.query.filter_by(
|
||||||
distribusiname=distribusiname
|
distribusiname=distribusiname
|
||||||
).first()
|
).first()
|
||||||
if distribusi.userid is user.id:
|
if distribusi.userid is user.id:
|
||||||
db.session.delete(distribusi)
|
db.session.delete(distribusi)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
userfolder = os.path.join("stash", distribusi.distribusiname)
|
userfolder = os.path.join("stash", distribusi.distribusiname)
|
||||||
if os.path.exists(userfolder):
|
if os.path.exists(userfolder):
|
||||||
shutil.rmtree(userfolder)
|
shutil.rmtree(userfolder)
|
||||||
cssfolder = os.path.join(
|
cssfolder = os.path.join(
|
||||||
"themes/userthemes", distribusi.distribusiname
|
"themes/userthemes", distribusi.distribusiname
|
||||||
)
|
)
|
||||||
if os.path.exists(cssfolder):
|
if os.path.exists(cssfolder):
|
||||||
shutil.rmtree(cssfolder)
|
shutil.rmtree(cssfolder)
|
||||||
if distribusi.publictheme is not None:
|
if distribusi.publictheme is not None:
|
||||||
publicthemefolder = os.path.join(
|
publicthemefolder = os.path.join(
|
||||||
"themes/publicthemes", distribusi.distribusiname
|
"themes/publicthemes", distribusi.distribusiname
|
||||||
)
|
)
|
||||||
if os.path.exists(publicthemefolder):
|
if os.path.exists(publicthemefolder):
|
||||||
shutil.rmtree(publicthemefolder)
|
shutil.rmtree(publicthemefolder)
|
||||||
# SelectField error is list is a tuple?? why??
|
# SelectField error is list is a tuple?? why??
|
||||||
# selectorform.distribusis.errors.append("Distribusi deleted!")
|
# selectorform.distribusis.errors.append("Distribusi deleted!")
|
||||||
except (InvalidRequestError, DataError, InterfaceError, DatabaseError):
|
except (InvalidRequestError, DataError, InterfaceError, DatabaseError):
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
# selectorform.distribusis.errors.append("Unknown error occured!")
|
# selectorform.distribusis.errors.append("Unknown error occured!")
|
||||||
flash("An error occured !", "danger")
|
flash("An error occured !", "danger")
|
||||||
return selectorform
|
return selectorform
|
||||||
|
|
||||||
|
|
||||||
def SelectCurrentDistribusi(distribusiname):
|
def SelectCurrentDistribusi(distribusiname):
|
||||||
if not current_user.is_authenticated:
|
if not current_user.is_authenticated:
|
||||||
return
|
return
|
||||||
user = User.query.filter_by(email=current_user.email).first()
|
user = User.query.filter_by(email=current_user.email).first()
|
||||||
try:
|
try:
|
||||||
user.currentdistribusi = distribusiname
|
user.currentdistribusi = distribusiname
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
except (InvalidRequestError, DataError, InterfaceError, DatabaseError):
|
except (InvalidRequestError, DataError, InterfaceError, DatabaseError):
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash("An error occured !", "danger")
|
flash("An error occured !", "danger")
|
||||||
|
|
||||||
|
|
||||||
def DistribusiSelected():
|
def DistribusiSelected():
|
||||||
user = User.query.filter_by(email=current_user.email).first()
|
user = User.query.filter_by(email=current_user.email).first()
|
||||||
if user.currentdistribusi is None:
|
if user.currentdistribusi is None:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def SelectorVisible():
|
def SelectorVisible():
|
||||||
has_distribusi = UserHelper.has_distribusi()
|
has_distribusi = UserHelper.has_distribusi()
|
||||||
distribusi_selected = DistribusiSelected()
|
distribusi_selected = DistribusiSelected()
|
||||||
if distribusi_selected:
|
if distribusi_selected:
|
||||||
return False
|
return False
|
||||||
if not has_distribusi:
|
if not has_distribusi:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def RenderDistribusiTemplate(selectorform, uploadform, current_distribusi):
|
def RenderDistribusiTemplate(selectorform, uploadform, current_distribusi):
|
||||||
distribusiform = DistribusiForm()
|
distribusiform = DistribusiForm()
|
||||||
themeform = ThemeForm()
|
themeform = ThemeForm()
|
||||||
publicthemeform = PublicThemeForm()
|
publicthemeform = PublicThemeForm()
|
||||||
publicthemeform.publicthemes.choices = DistribusisInfo.publicthemes()
|
publicthemeform.publicthemes.choices = DistribusisInfo.publicthemes()
|
||||||
files_uploaded = UserHelper.is_zip_uploaded(current_distribusi)
|
files_uploaded = UserHelper.is_zip_uploaded(current_distribusi)
|
||||||
distribusi_live = UserHelper.is_distribusi_live(current_distribusi)
|
distribusi_live = UserHelper.is_distribusi_live(current_distribusi)
|
||||||
|
|
||||||
# because the user has chosen to update his distribusi, we assume
|
# because the user has chosen to update his distribusi, we assume
|
||||||
# no selected css.
|
# no selected css.
|
||||||
css_selected = False
|
css_selected = False
|
||||||
selectorvisible = SelectorVisible()
|
selectorvisible = SelectorVisible()
|
||||||
limit_reached = UserHelper.distribusi_limit_reached()
|
limit_reached = UserHelper.distribusi_limit_reached()
|
||||||
template = render_template(
|
template = render_template(
|
||||||
"distribusi.html",
|
"distribusi.html",
|
||||||
uploadform=uploadform,
|
uploadform=uploadform,
|
||||||
distribusiform=distribusiform,
|
distribusiform=distribusiform,
|
||||||
themeform=themeform,
|
themeform=themeform,
|
||||||
publicthemeform=publicthemeform,
|
publicthemeform=publicthemeform,
|
||||||
selectorform=selectorform,
|
selectorform=selectorform,
|
||||||
files_uploaded=files_uploaded,
|
files_uploaded=files_uploaded,
|
||||||
distribusi_live=distribusi_live,
|
distribusi_live=distribusi_live,
|
||||||
css_selected=css_selected,
|
css_selected=css_selected,
|
||||||
selectorvisible=selectorvisible,
|
selectorvisible=selectorvisible,
|
||||||
limit_reached=limit_reached,
|
limit_reached=limit_reached,
|
||||||
)
|
)
|
||||||
return template
|
return template
|
||||||
|
@ -5,34 +5,34 @@ from models.user_model import User
|
|||||||
|
|
||||||
|
|
||||||
class DistribusisInfo:
|
class DistribusisInfo:
|
||||||
def userdistribusinames():
|
def userdistribusinames():
|
||||||
distribusinames = []
|
distribusinames = []
|
||||||
user = User.query.filter_by(email=current_user.email).first()
|
user = User.query.filter_by(email=current_user.email).first()
|
||||||
for distribusi in Distribusis.query.filter_by(userid=user.id).all():
|
for distribusi in Distribusis.query.filter_by(userid=user.id).all():
|
||||||
distribusinames.append(distribusi.distribusiname)
|
distribusinames.append(distribusi.distribusiname)
|
||||||
return distribusinames
|
return distribusinames
|
||||||
|
|
||||||
def publicthemes():
|
def publicthemes():
|
||||||
publicthemes = []
|
publicthemes = []
|
||||||
distribusis = Distribusis.query.filter(
|
distribusis = Distribusis.query.filter(
|
||||||
Distribusis.publictheme.isnot(None)
|
Distribusis.publictheme.isnot(None)
|
||||||
).all()
|
).all()
|
||||||
for distribusi in distribusis:
|
for distribusi in distribusis:
|
||||||
user = User.query.filter_by(id=distribusi.userid).first()
|
user = User.query.filter_by(id=distribusi.userid).first()
|
||||||
publictheme = (
|
publictheme = (
|
||||||
f"{distribusi.distribusiname}/{distribusi.publictheme}",
|
f"{distribusi.distribusiname}/{distribusi.publictheme}",
|
||||||
f"""{distribusi.publictheme} used in {distribusi.distribusiname}
|
f"""{distribusi.publictheme} used in {distribusi.distribusiname}
|
||||||
made by {user.username}""",
|
made by {user.username}""",
|
||||||
)
|
)
|
||||||
publicthemes.append(publictheme)
|
publicthemes.append(publictheme)
|
||||||
return publicthemes
|
return publicthemes
|
||||||
|
|
||||||
def visibledistribusis():
|
def visibledistribusis():
|
||||||
distribusis = Distribusis.query.filter(
|
distribusis = Distribusis.query.filter(
|
||||||
Distribusis.visible.isnot(False)
|
Distribusis.visible.isnot(False)
|
||||||
).all()
|
).all()
|
||||||
return distribusis
|
return distribusis
|
||||||
|
|
||||||
def getuserdistribusis(useremail):
|
def getuserdistribusis(useremail):
|
||||||
user = User.query.filter_by(email=useremail).first()
|
user = User.query.filter_by(email=useremail).first()
|
||||||
return Distribusis.query.filter_by(userid=user.id).all()
|
return Distribusis.query.filter_by(userid=user.id).all()
|
||||||
|
@ -8,10 +8,10 @@ from distribusi.distribusi import distribusify
|
|||||||
from flask import flash, redirect, render_template, url_for
|
from flask import flash, redirect, render_template, url_for
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from sqlalchemy.exc import (
|
from sqlalchemy.exc import (
|
||||||
DatabaseError,
|
DatabaseError,
|
||||||
DataError,
|
DataError,
|
||||||
InterfaceError,
|
InterfaceError,
|
||||||
InvalidRequestError,
|
InvalidRequestError,
|
||||||
)
|
)
|
||||||
|
|
||||||
from app import db
|
from app import db
|
||||||
@ -32,112 +32,112 @@ from statuspengguna.helper import UserHelper
|
|||||||
|
|
||||||
|
|
||||||
def DistribusiWorkflow():
|
def DistribusiWorkflow():
|
||||||
distribusiform = DistribusiForm()
|
distribusiform = DistribusiForm()
|
||||||
current_distribusi = UserHelper.current_distribusi()
|
current_distribusi = UserHelper.current_distribusi()
|
||||||
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(
|
distribusi = Distribusis.query.filter_by(
|
||||||
distribusiname=current_distribusi
|
distribusiname=current_distribusi
|
||||||
).first()
|
).first()
|
||||||
|
|
||||||
if distribusiform.validate_on_submit():
|
if distribusiform.validate_on_submit():
|
||||||
userfolder = os.path.join("stash", distribusi.distribusiname)
|
userfolder = os.path.join("stash", distribusi.distribusiname)
|
||||||
cssfile = GetCssFile(distribusi)
|
cssfile = GetCssFile(distribusi)
|
||||||
UnzipDistribusiFiles(distribusi, userfolder)
|
UnzipDistribusiFiles(distribusi, userfolder)
|
||||||
CleanUpDistribusiFiles(userfolder)
|
CleanUpDistribusiFiles(userfolder)
|
||||||
RunDistribusi(userfolder, cssfile)
|
RunDistribusi(userfolder, cssfile)
|
||||||
SetDistribusiToVisible(distribusi, user)
|
SetDistribusiToVisible(distribusi, user)
|
||||||
DeleteCssFile(cssfile)
|
DeleteCssFile(cssfile)
|
||||||
return redirect(url_for("index"))
|
return redirect(url_for("index"))
|
||||||
|
|
||||||
return RenderDistribusiTemplate(distribusiform, current_distribusi)
|
return RenderDistribusiTemplate(distribusiform, current_distribusi)
|
||||||
|
|
||||||
|
|
||||||
def UnzipDistribusiFiles(distribusi, userfolder):
|
def UnzipDistribusiFiles(distribusi, userfolder):
|
||||||
zipfilename = "{}.zip".format(distribusi.distribusiname)
|
zipfilename = "{}.zip".format(distribusi.distribusiname)
|
||||||
unzipfile = os.path.join(userfolder, zipfilename)
|
unzipfile = os.path.join(userfolder, zipfilename)
|
||||||
|
|
||||||
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:
|
||||||
zip_ref.extractall(userfolder)
|
zip_ref.extractall(userfolder)
|
||||||
# after extracting all files remove zip file.
|
# after extracting all files remove zip file.
|
||||||
if os.path.exists(unzipfile):
|
if os.path.exists(unzipfile):
|
||||||
os.remove(os.path.join(userfolder, zipfilename))
|
os.remove(os.path.join(userfolder, zipfilename))
|
||||||
|
|
||||||
|
|
||||||
def CleanUpDistribusiFiles(userfolder):
|
def CleanUpDistribusiFiles(userfolder):
|
||||||
if os.path.exists(userfolder):
|
if os.path.exists(userfolder):
|
||||||
RemoveMacFolders(userfolder)
|
RemoveMacFolders(userfolder)
|
||||||
|
|
||||||
|
|
||||||
def RemoveMacFolders(path):
|
def RemoveMacFolders(path):
|
||||||
for filename in os.listdir(path):
|
for filename in os.listdir(path):
|
||||||
fullpath = os.path.join(path, filename)
|
fullpath = os.path.join(path, filename)
|
||||||
if filename.startswith("."):
|
if filename.startswith("."):
|
||||||
if os.path.isdir(fullpath):
|
if os.path.isdir(fullpath):
|
||||||
shutil.rmtree(fullpath)
|
shutil.rmtree(fullpath)
|
||||||
else:
|
else:
|
||||||
os.remove(fullpath)
|
os.remove(fullpath)
|
||||||
if filename == "__MACOSX":
|
if filename == "__MACOSX":
|
||||||
shutil.rmtree(fullpath)
|
shutil.rmtree(fullpath)
|
||||||
if os.path.isdir(fullpath):
|
if os.path.isdir(fullpath):
|
||||||
RemoveMacFolders(fullpath)
|
RemoveMacFolders(fullpath)
|
||||||
|
|
||||||
|
|
||||||
def GetCssFile(distribusi):
|
def GetCssFile(distribusi):
|
||||||
cssfile = ""
|
cssfile = ""
|
||||||
cssfolder = os.path.join("themes/userthemes", distribusi.distribusiname)
|
cssfolder = os.path.join("themes/userthemes", distribusi.distribusiname)
|
||||||
if os.path.exists(cssfolder):
|
if os.path.exists(cssfolder):
|
||||||
for filename in os.listdir(cssfolder):
|
for filename in os.listdir(cssfolder):
|
||||||
if filename.endswith(".css"):
|
if filename.endswith(".css"):
|
||||||
cssfile = os.path.join(cssfolder, filename)
|
cssfile = os.path.join(cssfolder, filename)
|
||||||
return cssfile
|
return cssfile
|
||||||
|
|
||||||
|
|
||||||
def RunDistribusi(userfolder, cssfile):
|
def RunDistribusi(userfolder, cssfile):
|
||||||
parser = build_argparser()
|
parser = build_argparser()
|
||||||
args = parser.parse_args(["-t", "--menu-with-index", "-s", cssfile])
|
args = parser.parse_args(["-t", "--menu-with-index", "-s", cssfile])
|
||||||
distribusify(args, userfolder)
|
distribusify(args, userfolder)
|
||||||
|
|
||||||
|
|
||||||
def SetDistribusiToVisible(distribusi, user):
|
def SetDistribusiToVisible(distribusi, user):
|
||||||
try:
|
try:
|
||||||
distribusi.visible = True
|
distribusi.visible = True
|
||||||
user.currentdistribusi = None
|
user.currentdistribusi = None
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
except (InvalidRequestError, DataError, InterfaceError, DatabaseError):
|
except (InvalidRequestError, DataError, InterfaceError, DatabaseError):
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash("Unknown error occured!")
|
flash("Unknown error occured!")
|
||||||
|
|
||||||
|
|
||||||
def DeleteCssFile(cssfile):
|
def DeleteCssFile(cssfile):
|
||||||
if os.path.exists(cssfile):
|
if os.path.exists(cssfile):
|
||||||
os.remove(cssfile)
|
os.remove(cssfile)
|
||||||
|
|
||||||
|
|
||||||
def RenderDistribusiTemplate(distribusiform, current_distribusi):
|
def RenderDistribusiTemplate(distribusiform, current_distribusi):
|
||||||
uploadform = UploadForm()
|
uploadform = UploadForm()
|
||||||
themeform = ThemeForm()
|
themeform = ThemeForm()
|
||||||
publicthemeform = PublicThemeForm()
|
publicthemeform = PublicThemeForm()
|
||||||
publicthemeform.publicthemes.choices = DistribusisInfo.publicthemes()
|
publicthemeform.publicthemes.choices = DistribusisInfo.publicthemes()
|
||||||
selectorform = SelectorForm()
|
selectorform = SelectorForm()
|
||||||
selectorform.distribusis.choices = DistribusisInfo.userdistribusinames()
|
selectorform.distribusis.choices = DistribusisInfo.userdistribusinames()
|
||||||
selectorvisible = SelectorVisible()
|
selectorvisible = SelectorVisible()
|
||||||
|
|
||||||
files_uploaded = UserHelper.is_zip_uploaded(current_distribusi)
|
files_uploaded = UserHelper.is_zip_uploaded(current_distribusi)
|
||||||
distribusi_live = UserHelper.is_distribusi_live(current_distribusi)
|
distribusi_live = UserHelper.is_distribusi_live(current_distribusi)
|
||||||
css_selected = UserHelper.is_css_selected(current_distribusi)
|
css_selected = UserHelper.is_css_selected(current_distribusi)
|
||||||
limit_reached = UserHelper.distribusi_limit_reached()
|
limit_reached = UserHelper.distribusi_limit_reached()
|
||||||
template = render_template(
|
template = render_template(
|
||||||
"distribusi.html",
|
"distribusi.html",
|
||||||
uploadform=uploadform,
|
uploadform=uploadform,
|
||||||
distribusiform=distribusiform,
|
distribusiform=distribusiform,
|
||||||
themeform=themeform,
|
themeform=themeform,
|
||||||
publicthemeform=publicthemeform,
|
publicthemeform=publicthemeform,
|
||||||
selectorform=selectorform,
|
selectorform=selectorform,
|
||||||
files_uploaded=files_uploaded,
|
files_uploaded=files_uploaded,
|
||||||
distribusi_live=distribusi_live,
|
distribusi_live=distribusi_live,
|
||||||
css_selected=css_selected,
|
css_selected=css_selected,
|
||||||
selectorvisible=selectorvisible,
|
selectorvisible=selectorvisible,
|
||||||
limit_reached=limit_reached,
|
limit_reached=limit_reached,
|
||||||
)
|
)
|
||||||
return template
|
return template
|
||||||
|
@ -5,10 +5,10 @@ import bleach
|
|||||||
from bleach_allowlist import all_styles
|
from bleach_allowlist import all_styles
|
||||||
from flask import render_template
|
from flask import render_template
|
||||||
from sqlalchemy.exc import (
|
from sqlalchemy.exc import (
|
||||||
DatabaseError,
|
DatabaseError,
|
||||||
DataError,
|
DataError,
|
||||||
InterfaceError,
|
InterfaceError,
|
||||||
InvalidRequestError,
|
InvalidRequestError,
|
||||||
)
|
)
|
||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
|
|
||||||
@ -25,175 +25,175 @@ from statuspengguna.helper import UserHelper
|
|||||||
|
|
||||||
|
|
||||||
def Editor():
|
def Editor():
|
||||||
editorform = EditorForm()
|
editorform = EditorForm()
|
||||||
current_distribusi = UserHelper.current_distribusi()
|
current_distribusi = UserHelper.current_distribusi()
|
||||||
if editorform.validate_on_submit():
|
if editorform.validate_on_submit():
|
||||||
ValidateEditCssForm(editorform, current_distribusi)
|
ValidateEditCssForm(editorform, current_distribusi)
|
||||||
return RenderDistribusiTemplate(current_distribusi)
|
return RenderDistribusiTemplate(current_distribusi)
|
||||||
|
|
||||||
return RenderEditorTemplate(editorform, current_distribusi)
|
return RenderEditorTemplate(editorform, current_distribusi)
|
||||||
|
|
||||||
|
|
||||||
def ValidateEditCssForm(editorform, current_distribusi):
|
def ValidateEditCssForm(editorform, current_distribusi):
|
||||||
newcssfolder = os.path.join("themes/userthemes", current_distribusi)
|
newcssfolder = os.path.join("themes/userthemes", current_distribusi)
|
||||||
if os.path.exists(newcssfolder):
|
if os.path.exists(newcssfolder):
|
||||||
shutil.rmtree(newcssfolder)
|
shutil.rmtree(newcssfolder)
|
||||||
|
|
||||||
publicfolder = os.path.join("themes/publicthemes", current_distribusi)
|
publicfolder = os.path.join("themes/publicthemes", current_distribusi)
|
||||||
if os.path.exists(publicfolder):
|
if os.path.exists(publicfolder):
|
||||||
shutil.rmtree(publicfolder)
|
shutil.rmtree(publicfolder)
|
||||||
|
|
||||||
if editorform.public.data:
|
if editorform.public.data:
|
||||||
MakePublicTheme(editorform, current_distribusi)
|
MakePublicTheme(editorform, current_distribusi)
|
||||||
if editorform.cssfile.data:
|
if editorform.cssfile.data:
|
||||||
SaveUploadCssFile(editorform, publicfolder)
|
SaveUploadCssFile(editorform, publicfolder)
|
||||||
CopyPublicToUserFolder(editorform, publicfolder, newcssfolder)
|
CopyPublicToUserFolder(editorform, publicfolder, newcssfolder)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
WriteCssToFile(editorform, publicfolder)
|
WriteCssToFile(editorform, publicfolder)
|
||||||
|
|
||||||
if editorform.cssfile.data:
|
if editorform.cssfile.data:
|
||||||
SaveUploadCssFile(editorform, newcssfolder)
|
SaveUploadCssFile(editorform, newcssfolder)
|
||||||
return
|
return
|
||||||
if editorform.cssname.data:
|
if editorform.cssname.data:
|
||||||
WriteCssToFile(editorform, newcssfolder)
|
WriteCssToFile(editorform, newcssfolder)
|
||||||
|
|
||||||
|
|
||||||
def SaveUploadCssFile(editorform, newcssfolder):
|
def SaveUploadCssFile(editorform, newcssfolder):
|
||||||
if not os.path.exists(newcssfolder):
|
if not os.path.exists(newcssfolder):
|
||||||
os.mkdir(newcssfolder)
|
os.mkdir(newcssfolder)
|
||||||
cssfile = editorform.cssfile.data
|
cssfile = editorform.cssfile.data
|
||||||
cssfilename = f"{secure_filename(editorform.cssname.data)}.css"
|
cssfilename = f"{secure_filename(editorform.cssname.data)}.css"
|
||||||
cssfile.save(os.path.join(newcssfolder, cssfilename))
|
cssfile.save(os.path.join(newcssfolder, cssfilename))
|
||||||
openfile = open(os.path.join(newcssfolder, cssfilename), "r")
|
openfile = open(os.path.join(newcssfolder, cssfilename), "r")
|
||||||
cleancss = bleach.clean(openfile.read(), all_styles)
|
cleancss = bleach.clean(openfile.read(), all_styles)
|
||||||
cleancss = cleancss.replace(">", ">")
|
cleancss = cleancss.replace(">", ">")
|
||||||
openfile.close()
|
openfile.close()
|
||||||
cleanfile = open(os.path.join(newcssfolder, cssfilename), "w")
|
cleanfile = open(os.path.join(newcssfolder, cssfilename), "w")
|
||||||
cleanfile.write(cleancss)
|
cleanfile.write(cleancss)
|
||||||
cleanfile.close()
|
cleanfile.close()
|
||||||
|
|
||||||
|
|
||||||
def WriteCssToFile(editorform, newcssfolder):
|
def WriteCssToFile(editorform, newcssfolder):
|
||||||
if not os.path.exists(newcssfolder):
|
if not os.path.exists(newcssfolder):
|
||||||
os.mkdir(newcssfolder)
|
os.mkdir(newcssfolder)
|
||||||
|
|
||||||
cssfilename = f"{secure_filename(editorform.cssname.data)}.css"
|
cssfilename = f"{secure_filename(editorform.cssname.data)}.css"
|
||||||
cleancss = bleach.clean(editorform.css.data, all_styles)
|
cleancss = bleach.clean(editorform.css.data, all_styles)
|
||||||
cleancss = cleancss.replace(">", ">")
|
cleancss = cleancss.replace(">", ">")
|
||||||
with open(os.path.join(newcssfolder, cssfilename), "w") as cssfile:
|
with open(os.path.join(newcssfolder, cssfilename), "w") as cssfile:
|
||||||
cssfile.write(cleancss)
|
cssfile.write(cleancss)
|
||||||
cssfile.close
|
cssfile.close
|
||||||
|
|
||||||
|
|
||||||
def CopyPublicToUserFolder(editorform, publicfolder, newcssfolder):
|
def CopyPublicToUserFolder(editorform, publicfolder, newcssfolder):
|
||||||
if not os.path.exists(newcssfolder):
|
if not os.path.exists(newcssfolder):
|
||||||
os.mkdir(newcssfolder)
|
os.mkdir(newcssfolder)
|
||||||
copycssfile = os.path.join(
|
copycssfile = os.path.join(
|
||||||
publicfolder, f"{secure_filename(editorform.cssname.data)}.css"
|
publicfolder, f"{secure_filename(editorform.cssname.data)}.css"
|
||||||
)
|
)
|
||||||
print(f"copying file: {copycssfile}")
|
print(f"copying file: {copycssfile}")
|
||||||
print(f"to folder: {newcssfolder}")
|
print(f"to folder: {newcssfolder}")
|
||||||
shutil.copy(copycssfile, newcssfolder)
|
shutil.copy(copycssfile, newcssfolder)
|
||||||
|
|
||||||
|
|
||||||
def MakePublicTheme(editorform, current_distribusi):
|
def MakePublicTheme(editorform, current_distribusi):
|
||||||
try:
|
try:
|
||||||
distribusi = Distribusis.query.filter_by(
|
distribusi = Distribusis.query.filter_by(
|
||||||
distribusiname=current_distribusi
|
distribusiname=current_distribusi
|
||||||
).first()
|
).first()
|
||||||
distribusi.publictheme = secure_filename(editorform.cssname.data)
|
distribusi.publictheme = secure_filename(editorform.cssname.data)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
except InvalidRequestError:
|
except InvalidRequestError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
editorform.public.errors.append("Something went wrong!")
|
editorform.public.errors.append("Something went wrong!")
|
||||||
except DataError:
|
except DataError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
editorform.public.errors.append("Invalid Entry")
|
editorform.public.errors.append("Invalid Entry")
|
||||||
except InterfaceError:
|
except InterfaceError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
editorform.public.errors.append("Error connecting to the database")
|
editorform.public.errors.append("Error connecting to the database")
|
||||||
except DatabaseError:
|
except DatabaseError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
editorform.public.errors.append("Error connecting to the database")
|
editorform.public.errors.append("Error connecting to the database")
|
||||||
|
|
||||||
|
|
||||||
def RenderDistribusiTemplate(current_distribusi):
|
def RenderDistribusiTemplate(current_distribusi):
|
||||||
uploadform = UploadForm()
|
uploadform = UploadForm()
|
||||||
distribusiform = DistribusiForm()
|
distribusiform = DistribusiForm()
|
||||||
themeform = ThemeForm()
|
themeform = ThemeForm()
|
||||||
publicthemeform = PublicThemeForm()
|
publicthemeform = PublicThemeForm()
|
||||||
publicthemeform.publicthemes.choices = DistribusisInfo.publicthemes()
|
publicthemeform.publicthemes.choices = DistribusisInfo.publicthemes()
|
||||||
selectorform = SelectorForm()
|
selectorform = SelectorForm()
|
||||||
|
|
||||||
files_uploaded = UserHelper.is_zip_uploaded(current_distribusi)
|
files_uploaded = UserHelper.is_zip_uploaded(current_distribusi)
|
||||||
distribusi_live = UserHelper.is_distribusi_live(current_distribusi)
|
distribusi_live = UserHelper.is_distribusi_live(current_distribusi)
|
||||||
css_selected = True
|
css_selected = True
|
||||||
selectorvisible = False
|
selectorvisible = False
|
||||||
limit_reached = UserHelper.distribusi_limit_reached()
|
limit_reached = UserHelper.distribusi_limit_reached()
|
||||||
template = render_template(
|
template = render_template(
|
||||||
"distribusi.html",
|
"distribusi.html",
|
||||||
uploadform=uploadform,
|
uploadform=uploadform,
|
||||||
distribusiform=distribusiform,
|
distribusiform=distribusiform,
|
||||||
themeform=themeform,
|
themeform=themeform,
|
||||||
publicthemeform=publicthemeform,
|
publicthemeform=publicthemeform,
|
||||||
selectorform=selectorform,
|
selectorform=selectorform,
|
||||||
files_uploaded=files_uploaded,
|
files_uploaded=files_uploaded,
|
||||||
distribusi_live=distribusi_live,
|
distribusi_live=distribusi_live,
|
||||||
css_selected=css_selected,
|
css_selected=css_selected,
|
||||||
selectorvisible=selectorvisible,
|
selectorvisible=selectorvisible,
|
||||||
limit_reached=limit_reached,
|
limit_reached=limit_reached,
|
||||||
)
|
)
|
||||||
return template
|
return template
|
||||||
|
|
||||||
|
|
||||||
def RenderEditorTemplate(editorform, current_distribusi):
|
def RenderEditorTemplate(editorform, current_distribusi):
|
||||||
htmlplaceholder = HtmlPlaceholder()
|
htmlplaceholder = HtmlPlaceholder()
|
||||||
|
|
||||||
cssplaceholder = CssPlaceholder(current_distribusi)
|
cssplaceholder = CssPlaceholder(current_distribusi)
|
||||||
editorform.css.data = cssplaceholder
|
editorform.css.data = cssplaceholder
|
||||||
|
|
||||||
files_uploaded = UserHelper.is_zip_uploaded(current_distribusi)
|
files_uploaded = UserHelper.is_zip_uploaded(current_distribusi)
|
||||||
distribusi_live = UserHelper.is_distribusi_live(current_distribusi)
|
distribusi_live = UserHelper.is_distribusi_live(current_distribusi)
|
||||||
template = render_template(
|
template = render_template(
|
||||||
"editor.html",
|
"editor.html",
|
||||||
files_uploaded=files_uploaded,
|
files_uploaded=files_uploaded,
|
||||||
distribusi_live=distribusi_live,
|
distribusi_live=distribusi_live,
|
||||||
editorform=editorform,
|
editorform=editorform,
|
||||||
htmlplaceholder=htmlplaceholder,
|
htmlplaceholder=htmlplaceholder,
|
||||||
)
|
)
|
||||||
return template
|
return template
|
||||||
|
|
||||||
|
|
||||||
def CssPlaceholder(current_distribusi):
|
def CssPlaceholder(current_distribusi):
|
||||||
cssplaceholder = "Try out your CSS here"
|
cssplaceholder = "Try out your CSS here"
|
||||||
distribusi = Distribusis.query.filter_by(
|
distribusi = Distribusis.query.filter_by(
|
||||||
distribusiname=current_distribusi
|
distribusiname=current_distribusi
|
||||||
).first()
|
).first()
|
||||||
if distribusi is not None and distribusi.publictheme is not None:
|
if distribusi is not None and distribusi.publictheme is not None:
|
||||||
cssplaceholder = GetPublicCssFile(distribusi)
|
cssplaceholder = GetPublicCssFile(distribusi)
|
||||||
else:
|
else:
|
||||||
with open("themes/editor/placeholder.css") as f:
|
with open("themes/editor/placeholder.css") as f:
|
||||||
cssplaceholder = f.read()
|
cssplaceholder = f.read()
|
||||||
return cssplaceholder
|
return cssplaceholder
|
||||||
|
|
||||||
|
|
||||||
def HtmlPlaceholder():
|
def HtmlPlaceholder():
|
||||||
htmlplaceholder = "Write some test HTML here"
|
htmlplaceholder = "Write some test HTML here"
|
||||||
with open("themes/editor/placeholder.html") as f:
|
with open("themes/editor/placeholder.html") as f:
|
||||||
htmlplaceholder = f.read()
|
htmlplaceholder = f.read()
|
||||||
return htmlplaceholder
|
return htmlplaceholder
|
||||||
|
|
||||||
|
|
||||||
def GetPublicCssFile(distribusi):
|
def GetPublicCssFile(distribusi):
|
||||||
cssplaceholder = ""
|
cssplaceholder = ""
|
||||||
publicthemefolder = os.path.join(
|
publicthemefolder = os.path.join(
|
||||||
"themes/publicthemes", distribusi.distribusiname
|
"themes/publicthemes", distribusi.distribusiname
|
||||||
)
|
)
|
||||||
for filename in os.listdir(publicthemefolder):
|
for filename in os.listdir(publicthemefolder):
|
||||||
if filename.endswith(".css"):
|
if filename.endswith(".css"):
|
||||||
cssfile = os.path.join(publicthemefolder, filename)
|
cssfile = os.path.join(publicthemefolder, filename)
|
||||||
with open(cssfile) as f:
|
with open(cssfile) as f:
|
||||||
cssplaceholder = f.read()
|
cssplaceholder = f.read()
|
||||||
return cssplaceholder
|
return cssplaceholder
|
||||||
|
@ -13,55 +13,55 @@ from statuspengguna.helper import UserHelper
|
|||||||
|
|
||||||
|
|
||||||
def ThemeSelector():
|
def ThemeSelector():
|
||||||
themeform = ThemeForm()
|
themeform = ThemeForm()
|
||||||
publicthemeform = PublicThemeForm()
|
publicthemeform = PublicThemeForm()
|
||||||
publicthemeform.publicthemes.choices = DistribusisInfo.publicthemes()
|
publicthemeform.publicthemes.choices = DistribusisInfo.publicthemes()
|
||||||
current_distribusi = UserHelper.current_distribusi()
|
current_distribusi = UserHelper.current_distribusi()
|
||||||
if themeform.validate_on_submit():
|
if themeform.validate_on_submit():
|
||||||
copycssfile = os.path.join(
|
copycssfile = os.path.join(
|
||||||
"themes",
|
"themes",
|
||||||
f"{themeform.theme.data}.css",
|
f"{themeform.theme.data}.css",
|
||||||
)
|
)
|
||||||
MoveCssToUserFolder(current_distribusi, copycssfile)
|
MoveCssToUserFolder(current_distribusi, copycssfile)
|
||||||
if publicthemeform.validate_on_submit():
|
if publicthemeform.validate_on_submit():
|
||||||
copycssfile = os.path.join(
|
copycssfile = os.path.join(
|
||||||
"themes/publicthemes/",
|
"themes/publicthemes/",
|
||||||
f"{publicthemeform.publicthemes.data}.css",
|
f"{publicthemeform.publicthemes.data}.css",
|
||||||
)
|
)
|
||||||
MoveCssToUserFolder(current_distribusi, copycssfile)
|
MoveCssToUserFolder(current_distribusi, copycssfile)
|
||||||
return RenderDistribusiTemplate(
|
return RenderDistribusiTemplate(
|
||||||
themeform, publicthemeform, current_distribusi
|
themeform, publicthemeform, current_distribusi
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def MoveCssToUserFolder(current_distribusi, copycssfile):
|
def MoveCssToUserFolder(current_distribusi, copycssfile):
|
||||||
newcssfolder = os.path.join("themes/userthemes", current_distribusi)
|
newcssfolder = os.path.join("themes/userthemes", current_distribusi)
|
||||||
if not os.path.exists(newcssfolder):
|
if not os.path.exists(newcssfolder):
|
||||||
os.mkdir(newcssfolder)
|
os.mkdir(newcssfolder)
|
||||||
shutil.copy(copycssfile, newcssfolder)
|
shutil.copy(copycssfile, newcssfolder)
|
||||||
|
|
||||||
|
|
||||||
def RenderDistribusiTemplate(themeform, publicthemeform, current_distribusi):
|
def RenderDistribusiTemplate(themeform, publicthemeform, current_distribusi):
|
||||||
uploadform = UploadForm()
|
uploadform = UploadForm()
|
||||||
distribusiform = DistribusiForm()
|
distribusiform = DistribusiForm()
|
||||||
selectorform = SelectorForm()
|
selectorform = SelectorForm()
|
||||||
|
|
||||||
files_uploaded = UserHelper.is_zip_uploaded(current_distribusi)
|
files_uploaded = UserHelper.is_zip_uploaded(current_distribusi)
|
||||||
distribusi_live = UserHelper.is_distribusi_live(current_distribusi)
|
distribusi_live = UserHelper.is_distribusi_live(current_distribusi)
|
||||||
css_selected = UserHelper.is_css_selected(current_distribusi)
|
css_selected = UserHelper.is_css_selected(current_distribusi)
|
||||||
selectorvisible = False
|
selectorvisible = False
|
||||||
limit_reached = UserHelper.distribusi_limit_reached()
|
limit_reached = UserHelper.distribusi_limit_reached()
|
||||||
template = render_template(
|
template = render_template(
|
||||||
"distribusi.html",
|
"distribusi.html",
|
||||||
uploadform=uploadform,
|
uploadform=uploadform,
|
||||||
distribusiform=distribusiform,
|
distribusiform=distribusiform,
|
||||||
themeform=themeform,
|
themeform=themeform,
|
||||||
publicthemeform=publicthemeform,
|
publicthemeform=publicthemeform,
|
||||||
selectorform=selectorform,
|
selectorform=selectorform,
|
||||||
files_uploaded=files_uploaded,
|
files_uploaded=files_uploaded,
|
||||||
distribusi_live=distribusi_live,
|
distribusi_live=distribusi_live,
|
||||||
css_selected=css_selected,
|
css_selected=css_selected,
|
||||||
selectorvisible=selectorvisible,
|
selectorvisible=selectorvisible,
|
||||||
limit_reached=limit_reached,
|
limit_reached=limit_reached,
|
||||||
)
|
)
|
||||||
return template
|
return template
|
||||||
|
@ -4,11 +4,11 @@ import shutil
|
|||||||
from flask import flash
|
from flask import flash
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from sqlalchemy.exc import (
|
from sqlalchemy.exc import (
|
||||||
DatabaseError,
|
DatabaseError,
|
||||||
DataError,
|
DataError,
|
||||||
IntegrityError,
|
IntegrityError,
|
||||||
InterfaceError,
|
InterfaceError,
|
||||||
InvalidRequestError,
|
InvalidRequestError,
|
||||||
)
|
)
|
||||||
|
|
||||||
from app import db
|
from app import db
|
||||||
@ -20,76 +20,76 @@ from statuspengguna.helper import UserHelper
|
|||||||
|
|
||||||
|
|
||||||
def UploadNewDistribusi(uploadfolder):
|
def UploadNewDistribusi(uploadfolder):
|
||||||
uploadform = UploadForm()
|
uploadform = UploadForm()
|
||||||
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()
|
||||||
try:
|
try:
|
||||||
newdistribusi = Distribusis(
|
newdistribusi = Distribusis(
|
||||||
distribusiname=uploadform.sitename.data,
|
distribusiname=uploadform.sitename.data,
|
||||||
userid=user.id,
|
userid=user.id,
|
||||||
category=uploadform.category.data,
|
category=uploadform.category.data,
|
||||||
year=uploadform.year.data,
|
year=uploadform.year.data,
|
||||||
tags=uploadform.tags.data,
|
tags=uploadform.tags.data,
|
||||||
)
|
)
|
||||||
user.currentdistribusi = uploadform.sitename.data
|
user.currentdistribusi = uploadform.sitename.data
|
||||||
db.session.add(newdistribusi)
|
db.session.add(newdistribusi)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
uploadform.sitename.errors.append(
|
uploadform.sitename.errors.append(
|
||||||
"distribusi name already exists!"
|
"distribusi name already exists!"
|
||||||
)
|
)
|
||||||
flash("distribusi name already exists!", "warning")
|
flash("distribusi name already exists!", "warning")
|
||||||
return uploadform
|
return uploadform
|
||||||
except (InvalidRequestError, DataError, InterfaceError, DatabaseError):
|
except (InvalidRequestError, DataError, InterfaceError, DatabaseError):
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
uploadform.sitename.errors.append("Something went wrong!")
|
uploadform.sitename.errors.append("Something went wrong!")
|
||||||
flash("Something went wrong!", "danger")
|
flash("Something went wrong!", "danger")
|
||||||
return uploadform
|
return uploadform
|
||||||
SelectCurrentDistribusi(newdistribusi.distribusiname)
|
SelectCurrentDistribusi(newdistribusi.distribusiname)
|
||||||
zipfilename = "{}.zip".format(newdistribusi.distribusiname)
|
zipfilename = "{}.zip".format(newdistribusi.distribusiname)
|
||||||
zipfile = uploadform.zipfile.data
|
zipfile = uploadform.zipfile.data
|
||||||
zipfile.save(os.path.join(uploadfolder, zipfilename))
|
zipfile.save(os.path.join(uploadfolder, zipfilename))
|
||||||
|
|
||||||
newuserfolder = os.path.join("stash", newdistribusi.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(uploadfolder, zipfilename)
|
copyzipfile = os.path.join(uploadfolder, zipfilename)
|
||||||
shutil.copy(copyzipfile, newuserfolder)
|
shutil.copy(copyzipfile, newuserfolder)
|
||||||
os.remove(os.path.join(uploadfolder, zipfilename))
|
os.remove(os.path.join(uploadfolder, zipfilename))
|
||||||
|
|
||||||
return uploadform
|
return uploadform
|
||||||
|
|
||||||
|
|
||||||
def UploadUpdatedFiles(uploadfolder):
|
def UploadUpdatedFiles(uploadfolder):
|
||||||
uploadform = UploadForm()
|
uploadform = UploadForm()
|
||||||
if uploadform.validate_on_submit():
|
if uploadform.validate_on_submit():
|
||||||
try:
|
try:
|
||||||
current_distribusi = UserHelper.current_distribusi()
|
current_distribusi = UserHelper.current_distribusi()
|
||||||
distribusi = Distribusis.query.filter_by(
|
distribusi = Distribusis.query.filter_by(
|
||||||
distribusiname=current_distribusi
|
distribusiname=current_distribusi
|
||||||
).first()
|
).first()
|
||||||
distribusi.category = uploadform.category.data
|
distribusi.category = uploadform.category.data
|
||||||
distribusi.year = uploadform.year.data
|
distribusi.year = uploadform.year.data
|
||||||
distribusi.tags = uploadform.tags.data
|
distribusi.tags = uploadform.tags.data
|
||||||
distribusi.visible = False
|
distribusi.visible = False
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
except (InvalidRequestError, DataError, InterfaceError, DatabaseError):
|
except (InvalidRequestError, DataError, InterfaceError, DatabaseError):
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
uploadform.sitename.errors.append("Something went wrong!")
|
uploadform.sitename.errors.append("Something went wrong!")
|
||||||
|
|
||||||
zipfilename = "{}.zip".format(distribusi.distribusiname)
|
zipfilename = "{}.zip".format(distribusi.distribusiname)
|
||||||
zipfile = uploadform.zipfile.data
|
zipfile = uploadform.zipfile.data
|
||||||
zipfile.save(os.path.join(uploadfolder, zipfilename))
|
zipfile.save(os.path.join(uploadfolder, zipfilename))
|
||||||
|
|
||||||
newuserfolder = os.path.join("stash", distribusi.distribusiname)
|
newuserfolder = os.path.join("stash", distribusi.distribusiname)
|
||||||
if os.path.exists(newuserfolder):
|
if os.path.exists(newuserfolder):
|
||||||
shutil.rmtree(newuserfolder)
|
shutil.rmtree(newuserfolder)
|
||||||
os.mkdir(newuserfolder)
|
os.mkdir(newuserfolder)
|
||||||
|
|
||||||
copyzipfile = os.path.join(uploadfolder, zipfilename)
|
copyzipfile = os.path.join(uploadfolder, zipfilename)
|
||||||
shutil.copy(copyzipfile, newuserfolder)
|
shutil.copy(copyzipfile, newuserfolder)
|
||||||
os.remove(os.path.join(uploadfolder, zipfilename))
|
os.remove(os.path.join(uploadfolder, zipfilename))
|
||||||
|
|
||||||
return uploadform
|
return uploadform
|
||||||
|
@ -14,37 +14,37 @@ from statuspengguna.helper import UserHelper
|
|||||||
|
|
||||||
|
|
||||||
def UploadPage():
|
def UploadPage():
|
||||||
"render upload page section of distribusi workflow"
|
"render upload page section of distribusi workflow"
|
||||||
uploadfolder = APP.config["UPLOAD_FOLDER"]
|
uploadfolder = APP.config["UPLOAD_FOLDER"]
|
||||||
distribusiform = DistribusiForm()
|
distribusiform = DistribusiForm()
|
||||||
themeform = ThemeForm()
|
themeform = ThemeForm()
|
||||||
publicthemeform = PublicThemeForm()
|
publicthemeform = PublicThemeForm()
|
||||||
publicthemeform.publicthemes.choices = DistribusisInfo.publicthemes()
|
publicthemeform.publicthemes.choices = DistribusisInfo.publicthemes()
|
||||||
selectorform = SelectorForm()
|
selectorform = SelectorForm()
|
||||||
selectorform.distribusis.choices = DistribusisInfo.userdistribusinames()
|
selectorform.distribusis.choices = DistribusisInfo.userdistribusinames()
|
||||||
selectorvisible = SelectorVisible()
|
selectorvisible = SelectorVisible()
|
||||||
|
|
||||||
current_distribusi = UserHelper.current_distribusi()
|
current_distribusi = UserHelper.current_distribusi()
|
||||||
if current_distribusi == "new" or UserHelper.has_distribusi() is False:
|
if current_distribusi == "new" or UserHelper.has_distribusi() is False:
|
||||||
uploadform = UploadNewDistribusi(uploadfolder)
|
uploadform = UploadNewDistribusi(uploadfolder)
|
||||||
else:
|
else:
|
||||||
uploadform = UploadUpdatedFiles(uploadfolder)
|
uploadform = UploadUpdatedFiles(uploadfolder)
|
||||||
|
|
||||||
files_uploaded = UserHelper.is_zip_uploaded(uploadform.sitename.data)
|
files_uploaded = UserHelper.is_zip_uploaded(uploadform.sitename.data)
|
||||||
distribusi_live = UserHelper.is_distribusi_live(current_distribusi)
|
distribusi_live = UserHelper.is_distribusi_live(current_distribusi)
|
||||||
css_selected = UserHelper.is_css_selected(current_distribusi)
|
css_selected = UserHelper.is_css_selected(current_distribusi)
|
||||||
limit_reached = UserHelper.distribusi_limit_reached()
|
limit_reached = UserHelper.distribusi_limit_reached()
|
||||||
template = render_template(
|
template = render_template(
|
||||||
"distribusi.html",
|
"distribusi.html",
|
||||||
uploadform=uploadform,
|
uploadform=uploadform,
|
||||||
distribusiform=distribusiform,
|
distribusiform=distribusiform,
|
||||||
themeform=themeform,
|
themeform=themeform,
|
||||||
publicthemeform=publicthemeform,
|
publicthemeform=publicthemeform,
|
||||||
selectorform=selectorform,
|
selectorform=selectorform,
|
||||||
files_uploaded=files_uploaded,
|
files_uploaded=files_uploaded,
|
||||||
distribusi_live=distribusi_live,
|
distribusi_live=distribusi_live,
|
||||||
css_selected=css_selected,
|
css_selected=css_selected,
|
||||||
selectorvisible=selectorvisible,
|
selectorvisible=selectorvisible,
|
||||||
limit_reached=limit_reached,
|
limit_reached=limit_reached,
|
||||||
)
|
)
|
||||||
return template
|
return template
|
||||||
|
@ -6,70 +6,68 @@ from models.distribusi_model import Distribusis
|
|||||||
from models.distribusi_file_model import DistribusiFiles
|
from models.distribusi_file_model import DistribusiFiles
|
||||||
from app import create_app, get_app, db
|
from app import create_app, get_app, db
|
||||||
from sqlalchemy.exc import (
|
from sqlalchemy.exc import (
|
||||||
DatabaseError,
|
DatabaseError,
|
||||||
DataError,
|
DataError,
|
||||||
IntegrityError,
|
IntegrityError,
|
||||||
InterfaceError,
|
InterfaceError,
|
||||||
InvalidRequestError,
|
InvalidRequestError,
|
||||||
)
|
)
|
||||||
|
|
||||||
MIME_TYPE = magic.Magic(mime=True)
|
MIME_TYPE = magic.Magic(mime=True)
|
||||||
|
|
||||||
|
|
||||||
def _distribusi_file_with_type(distribusi, full_path):
|
def _distribusi_file_with_type(distribusi, full_path):
|
||||||
mime = MIME_TYPE.from_file(full_path)
|
mime = MIME_TYPE.from_file(full_path)
|
||||||
type_, subtype = mime.split("/")
|
type_, subtype = mime.split("/")
|
||||||
if type_ in FILE_TYPES:
|
if type_ in FILE_TYPES:
|
||||||
_add_distribusi_file_to_db(distribusi, full_path, type_)
|
_add_distribusi_file_to_db(distribusi, full_path, type_)
|
||||||
|
|
||||||
|
|
||||||
def _get_distribusi_from_path(path):
|
def _get_distribusi_from_path(path):
|
||||||
distribusi = Distribusis.query.filter_by(distribusiname=path).first()
|
distribusi = Distribusis.query.filter_by(distribusiname=path).first()
|
||||||
return distribusi
|
return distribusi
|
||||||
|
|
||||||
|
|
||||||
def _add_distribusi_file_to_db(distribusi, full_path, type):
|
def _add_distribusi_file_to_db(distribusi, full_path, type):
|
||||||
app = get_app()
|
app = get_app()
|
||||||
print(f"adding file to database: {full_path} type: {type}")
|
print(f"adding file to database: {full_path} type: {type}")
|
||||||
try:
|
try:
|
||||||
new_distribusi_file = DistribusiFiles(
|
new_distribusi_file = DistribusiFiles(
|
||||||
path=full_path,
|
path=full_path,
|
||||||
type=type,
|
type=type,
|
||||||
distribusi=distribusi.id,
|
distribusi=distribusi.id,
|
||||||
)
|
)
|
||||||
db.session.add(new_distribusi_file)
|
db.session.add(new_distribusi_file)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return
|
return
|
||||||
except InvalidRequestError:
|
except InvalidRequestError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
app.logger.error("Something went wrong!")
|
app.logger.error("Something went wrong!")
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
app.logger.error("File %s already exists!", full_path)
|
app.logger.error("File %s already exists!", full_path)
|
||||||
except DataError:
|
except DataError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
app.logger.error("%s Invalid Entry", full_path)
|
app.logger.error("%s Invalid Entry", full_path)
|
||||||
except InterfaceError:
|
except InterfaceError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
app.logger.error(
|
app.logger.error("Error connecting to the database")
|
||||||
"Error connecting to the database"
|
except DatabaseError:
|
||||||
)
|
db.session.rollback()
|
||||||
except DatabaseError:
|
app.logger.error("Error connecting to the database")
|
||||||
db.session.rollback()
|
|
||||||
app.logger.error(
|
|
||||||
"Error connecting to the database"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def add_distribusi_files(path):
|
def add_distribusi_files(path):
|
||||||
app = create_app()
|
app = create_app()
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
distribusi = _get_distribusi_from_path(path)
|
distribusi = _get_distribusi_from_path(path)
|
||||||
path = os.path.join("stash", path)
|
path = os.path.join("stash", path)
|
||||||
for root, dirs, files in os.walk(path, topdown=True):
|
for root, dirs, files in os.walk(path, topdown=True):
|
||||||
files = list(filter(lambda f: not f.startswith("."), files))
|
files = list(filter(lambda f: not f.startswith("."), files))
|
||||||
files = list(filter(lambda f: not f.endswith(".html"), files))
|
files = list(filter(lambda f: not f.endswith(".html"), files))
|
||||||
for file in files:
|
for file in files:
|
||||||
full_path = os.path.join(root, file)
|
full_path = os.path.join(root, file)
|
||||||
_distribusi_file_with_type(distribusi, full_path)
|
_distribusi_file_with_type(distribusi, full_path)
|
||||||
|
|
||||||
|
|
||||||
add_distribusi_files("2018-12-WttF-Mastodon-and-the-Fediverse")
|
add_distribusi_files("2018-12-WttF-Mastodon-and-the-Fediverse")
|
||||||
|
@ -5,19 +5,19 @@ from wtforms import BooleanField, SubmitField
|
|||||||
|
|
||||||
|
|
||||||
class AdminDistribusiForm(FlaskForm):
|
class AdminDistribusiForm(FlaskForm):
|
||||||
"""Admin Distribusi form."""
|
"""Admin Distribusi form."""
|
||||||
|
|
||||||
delete = SubmitField("Delete")
|
delete = SubmitField("Delete")
|
||||||
|
|
||||||
def distribusi_list_form_builder(distribusis):
|
def distribusi_list_form_builder(distribusis):
|
||||||
class DistribusiListForm(AdminDistribusiForm):
|
class DistribusiListForm(AdminDistribusiForm):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
for i, distribusi in enumerate(distribusis):
|
for i, distribusi in enumerate(distribusis):
|
||||||
setattr(
|
setattr(
|
||||||
DistribusiListForm,
|
DistribusiListForm,
|
||||||
f"distribusi_{i}",
|
f"distribusi_{i}",
|
||||||
BooleanField(label=distribusi.distribusiname),
|
BooleanField(label=distribusi.distribusiname),
|
||||||
)
|
)
|
||||||
|
|
||||||
return DistribusiListForm()
|
return DistribusiListForm()
|
||||||
|
@ -5,19 +5,19 @@ from wtforms import BooleanField, SubmitField
|
|||||||
|
|
||||||
|
|
||||||
class AdminUserForm(FlaskForm):
|
class AdminUserForm(FlaskForm):
|
||||||
"""Admin Userform form."""
|
"""Admin Userform form."""
|
||||||
|
|
||||||
def user_list_form_builder(users):
|
def user_list_form_builder(users):
|
||||||
class UserListForm(AdminUserForm):
|
class UserListForm(AdminUserForm):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
for i, user in enumerate(users):
|
for i, user in enumerate(users):
|
||||||
setattr(
|
setattr(
|
||||||
UserListForm,
|
UserListForm,
|
||||||
f"user_{i}",
|
f"user_{i}",
|
||||||
BooleanField(label=user.email),
|
BooleanField(label=user.email),
|
||||||
)
|
)
|
||||||
|
|
||||||
return UserListForm()
|
return UserListForm()
|
||||||
|
|
||||||
delete = SubmitField("Delete")
|
delete = SubmitField("Delete")
|
||||||
|
@ -3,6 +3,6 @@ from wtforms import SubmitField
|
|||||||
|
|
||||||
|
|
||||||
class DistribusiForm(FlaskForm):
|
class DistribusiForm(FlaskForm):
|
||||||
"""Distribusi class to launch your distribusi website"""
|
"""Distribusi class to launch your distribusi website"""
|
||||||
|
|
||||||
submit = SubmitField("Distribusi!")
|
submit = SubmitField("Distribusi!")
|
||||||
|
@ -3,33 +3,33 @@
|
|||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from flask_wtf.file import FileAllowed, FileField, FileSize
|
from flask_wtf.file import FileAllowed, FileField, FileSize
|
||||||
from wtforms import (
|
from wtforms import (
|
||||||
BooleanField,
|
BooleanField,
|
||||||
StringField,
|
StringField,
|
||||||
SubmitField,
|
SubmitField,
|
||||||
TextAreaField,
|
TextAreaField,
|
||||||
validators,
|
validators,
|
||||||
)
|
)
|
||||||
from wtforms.validators import Length
|
from wtforms.validators import Length
|
||||||
|
|
||||||
|
|
||||||
class EditorForm(FlaskForm):
|
class EditorForm(FlaskForm):
|
||||||
"""Css editor form class."""
|
"""Css editor form class."""
|
||||||
|
|
||||||
cssname = StringField(
|
cssname = StringField(
|
||||||
"fill in a name for your css style:",
|
"fill in a name for your css style:",
|
||||||
validators=[validators.InputRequired(), Length(5, 200)],
|
validators=[validators.InputRequired(), Length(5, 200)],
|
||||||
)
|
)
|
||||||
cssfile = FileField(
|
cssfile = FileField(
|
||||||
"(Optional) upload your own css file:",
|
"(Optional) upload your own css file:",
|
||||||
validators=[
|
validators=[
|
||||||
FileAllowed(["css"], "css files only!"),
|
FileAllowed(["css"], "css files only!"),
|
||||||
FileSize(
|
FileSize(
|
||||||
max_size=10485760,
|
max_size=10485760,
|
||||||
message="css file size must be smaller than 10MB",
|
message="css file size must be smaller than 10MB",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
css = TextAreaField()
|
css = TextAreaField()
|
||||||
public = BooleanField("Make your CSS public so others can use it")
|
public = BooleanField("Make your CSS public so others can use it")
|
||||||
|
|
||||||
submit = SubmitField("Save")
|
submit = SubmitField("Save")
|
||||||
|
@ -6,10 +6,10 @@ from wtforms.validators import Email, Length
|
|||||||
|
|
||||||
|
|
||||||
class ForgotPasswordForm(FlaskForm):
|
class ForgotPasswordForm(FlaskForm):
|
||||||
"""Forgotten password distribusiverse form class."""
|
"""Forgotten password distribusiverse form class."""
|
||||||
|
|
||||||
email = StringField(
|
email = StringField(
|
||||||
"Email address:",
|
"Email address:",
|
||||||
validators=[validators.InputRequired(), Email(), Length(6, 64)],
|
validators=[validators.InputRequired(), Email(), Length(6, 64)],
|
||||||
)
|
)
|
||||||
submit = SubmitField("Send email")
|
submit = SubmitField("Send email")
|
||||||
|
@ -6,13 +6,13 @@ from wtforms.validators import Email, Length
|
|||||||
|
|
||||||
|
|
||||||
class LoginForm(FlaskForm):
|
class LoginForm(FlaskForm):
|
||||||
"""Login distribusiverse form class."""
|
"""Login distribusiverse form class."""
|
||||||
|
|
||||||
email = StringField(
|
email = StringField(
|
||||||
"Email address:",
|
"Email address:",
|
||||||
validators=[validators.InputRequired(), Email(), Length(6, 64)],
|
validators=[validators.InputRequired(), Email(), Length(6, 64)],
|
||||||
)
|
)
|
||||||
password = PasswordField(
|
password = PasswordField(
|
||||||
"Password:", validators=[validators.InputRequired()]
|
"Password:", validators=[validators.InputRequired()]
|
||||||
)
|
)
|
||||||
submit = SubmitField("Sign In")
|
submit = SubmitField("Sign In")
|
||||||
|
@ -5,10 +5,10 @@ from wtforms import RadioField, SubmitField
|
|||||||
|
|
||||||
|
|
||||||
class PublicThemeForm(FlaskForm):
|
class PublicThemeForm(FlaskForm):
|
||||||
"""PublicTheme selection form."""
|
"""PublicTheme selection form."""
|
||||||
|
|
||||||
publicthemes = RadioField(
|
publicthemes = RadioField(
|
||||||
"Public themes from other distribusi-verse users:"
|
"Public themes from other distribusi-verse users:"
|
||||||
)
|
)
|
||||||
|
|
||||||
save = SubmitField("Save")
|
save = SubmitField("Save")
|
||||||
|
@ -6,33 +6,33 @@ from wtforms.validators import Email, EqualTo, Length
|
|||||||
|
|
||||||
|
|
||||||
class RegisterForm(FlaskForm):
|
class RegisterForm(FlaskForm):
|
||||||
"""Register for distribusi-verse form class"""
|
"""Register for distribusi-verse form class"""
|
||||||
|
|
||||||
username = StringField(
|
username = StringField(
|
||||||
"Username:",
|
"Username:",
|
||||||
validators=[validators.InputRequired(), Length(3, 150)],
|
validators=[validators.InputRequired(), Length(3, 150)],
|
||||||
)
|
)
|
||||||
|
|
||||||
email = StringField(
|
email = StringField(
|
||||||
"Email address:",
|
"Email address:",
|
||||||
validators=[
|
validators=[
|
||||||
validators.InputRequired(),
|
validators.InputRequired(),
|
||||||
Email(),
|
Email(),
|
||||||
Length(6, 128),
|
Length(6, 128),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
password = PasswordField(
|
password = PasswordField(
|
||||||
"New password:",
|
"New password:",
|
||||||
validators=[validators.InputRequired(), Length(12, 72)],
|
validators=[validators.InputRequired(), Length(12, 72)],
|
||||||
)
|
)
|
||||||
|
|
||||||
confirmpassword = PasswordField(
|
confirmpassword = PasswordField(
|
||||||
"Confirm your password:",
|
"Confirm your password:",
|
||||||
validators=[
|
validators=[
|
||||||
validators.InputRequired(),
|
validators.InputRequired(),
|
||||||
Length(12, 72),
|
Length(12, 72),
|
||||||
EqualTo("password", message="Passwords must match !"),
|
EqualTo("password", message="Passwords must match !"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
submit = SubmitField("Register to Distribusi-verse")
|
submit = SubmitField("Register to Distribusi-verse")
|
||||||
|
@ -6,18 +6,18 @@ from wtforms.validators import EqualTo, Length
|
|||||||
|
|
||||||
|
|
||||||
class ResetPasswordForm(FlaskForm):
|
class ResetPasswordForm(FlaskForm):
|
||||||
"""ResetPassword for distribusi-verse form class"""
|
"""ResetPassword for distribusi-verse form class"""
|
||||||
|
|
||||||
password = PasswordField(
|
password = PasswordField(
|
||||||
"New password:",
|
"New password:",
|
||||||
validators=[validators.InputRequired(), Length(12, 72)],
|
validators=[validators.InputRequired(), Length(12, 72)],
|
||||||
)
|
)
|
||||||
confirmpassword = PasswordField(
|
confirmpassword = PasswordField(
|
||||||
"Confirm your password:",
|
"Confirm your password:",
|
||||||
validators=[
|
validators=[
|
||||||
validators.InputRequired(),
|
validators.InputRequired(),
|
||||||
Length(12, 72),
|
Length(12, 72),
|
||||||
EqualTo("password", message="Passwords must match !"),
|
EqualTo("password", message="Passwords must match !"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
submit = SubmitField("Reset your password")
|
submit = SubmitField("Reset your password")
|
||||||
|
@ -3,12 +3,12 @@ from wtforms import SelectField, SubmitField
|
|||||||
|
|
||||||
|
|
||||||
class SelectorForm(FlaskForm):
|
class SelectorForm(FlaskForm):
|
||||||
distribusis = SelectField("Your existing distribusi:")
|
distribusis = SelectField("Your existing distribusi:")
|
||||||
|
|
||||||
new = SubmitField("new")
|
new = SubmitField("new")
|
||||||
|
|
||||||
update = SubmitField("update")
|
update = SubmitField("update")
|
||||||
|
|
||||||
describe = SubmitField("describe")
|
describe = SubmitField("describe")
|
||||||
|
|
||||||
delete = SubmitField("delete")
|
delete = SubmitField("delete")
|
||||||
|
@ -5,15 +5,15 @@ from wtforms import RadioField, SubmitField
|
|||||||
|
|
||||||
|
|
||||||
class ThemeForm(FlaskForm):
|
class ThemeForm(FlaskForm):
|
||||||
"""Basic theme selection form."""
|
"""Basic theme selection form."""
|
||||||
|
|
||||||
theme = RadioField(
|
theme = RadioField(
|
||||||
"Select your theme:",
|
"Select your theme:",
|
||||||
choices=[
|
choices=[
|
||||||
("hacking", "Hackers (black background, green text)"),
|
("hacking", "Hackers (black background, green text)"),
|
||||||
("peachsunset", "Peach sunset (single column)"),
|
("peachsunset", "Peach sunset (single column)"),
|
||||||
("masonry", "Masonry (white background, grid layout)"),
|
("masonry", "Masonry (white background, grid layout)"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
save = SubmitField("Save")
|
save = SubmitField("Save")
|
||||||
|
@ -1,85 +1,85 @@
|
|||||||
from flask_wtf import FlaskForm
|
from flask_wtf import FlaskForm
|
||||||
from flask_wtf.file import FileAllowed, FileField, FileRequired, FileSize
|
from flask_wtf.file import FileAllowed, FileField, FileRequired, FileSize
|
||||||
from wtforms import (
|
from wtforms import (
|
||||||
SelectField,
|
SelectField,
|
||||||
StringField,
|
StringField,
|
||||||
SubmitField,
|
SubmitField,
|
||||||
validators,
|
validators,
|
||||||
)
|
)
|
||||||
from wtforms.validators import (
|
from wtforms.validators import (
|
||||||
DataRequired,
|
DataRequired,
|
||||||
Length,
|
Length,
|
||||||
ValidationError,
|
ValidationError,
|
||||||
)
|
)
|
||||||
|
|
||||||
from app import settings
|
from app import settings
|
||||||
|
|
||||||
|
|
||||||
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 distribusiname(form, field):
|
def distribusiname(form, field):
|
||||||
if field.data.lower() == "new":
|
if field.data.lower() == "new":
|
||||||
raise ValidationError("Name has to be unique and not just new.")
|
raise ValidationError("Name has to be unique and not just new.")
|
||||||
|
|
||||||
def category_choices():
|
def category_choices():
|
||||||
APP = settings()
|
APP = settings()
|
||||||
config_categories = APP.config["categories"]
|
config_categories = APP.config["categories"]
|
||||||
categories = []
|
categories = []
|
||||||
for config_category in config_categories:
|
for config_category in config_categories:
|
||||||
categories.append((config_category, config_category))
|
categories.append((config_category, config_category))
|
||||||
return categories
|
return categories
|
||||||
|
|
||||||
def year_choices():
|
def year_choices():
|
||||||
APP = settings()
|
APP = settings()
|
||||||
start_time = APP.config["start_time"]
|
start_time = APP.config["start_time"]
|
||||||
end_time = APP.config["end_time"]
|
end_time = APP.config["end_time"]
|
||||||
year_range = range(start_time.year, end_time.year, 1)
|
year_range = range(start_time.year, end_time.year, 1)
|
||||||
year_choices = []
|
year_choices = []
|
||||||
for year in year_range:
|
for year in year_range:
|
||||||
year_choices.append((str(year), str(year)))
|
year_choices.append((str(year), str(year)))
|
||||||
return year_choices
|
return year_choices
|
||||||
|
|
||||||
sitename = StringField(
|
sitename = StringField(
|
||||||
"Name of your archive section:",
|
"Name of your archive section:",
|
||||||
validators=[
|
validators=[
|
||||||
validators.InputRequired(),
|
validators.InputRequired(),
|
||||||
Length(2, 100),
|
Length(2, 100),
|
||||||
distribusiname,
|
distribusiname,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
year = SelectField(
|
year = SelectField(
|
||||||
"Year:",
|
"Year:",
|
||||||
validate_choice=True,
|
validate_choice=True,
|
||||||
coerce=str,
|
coerce=str,
|
||||||
choices=year_choices,
|
choices=year_choices,
|
||||||
option_widget=None,
|
option_widget=None,
|
||||||
validators=[DataRequired()],
|
validators=[DataRequired()],
|
||||||
)
|
)
|
||||||
category = SelectField(
|
category = SelectField(
|
||||||
"Category:",
|
"Category:",
|
||||||
validate_choice=True,
|
validate_choice=True,
|
||||||
coerce=str,
|
coerce=str,
|
||||||
choices=category_choices,
|
choices=category_choices,
|
||||||
option_widget=None,
|
option_widget=None,
|
||||||
validators=[DataRequired()],
|
validators=[DataRequired()],
|
||||||
)
|
)
|
||||||
|
|
||||||
tags = StringField(
|
tags = StringField(
|
||||||
"Add search tags, seperated by commas. No need for the '#' sign:",
|
"Add search tags, seperated by commas. No need for the '#' sign:",
|
||||||
validators=[validators.InputRequired(), Length(3, 500)],
|
validators=[validators.InputRequired(), Length(3, 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!"),
|
||||||
FileRequired(),
|
FileRequired(),
|
||||||
FileSize(
|
FileSize(
|
||||||
max_size=1073741824,
|
max_size=1073741824,
|
||||||
message="Zipfile size must be smaller than 100MB",
|
message="Zipfile size must be smaller than 100MB",
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
submit = SubmitField("Upload")
|
submit = SubmitField("Upload")
|
||||||
|
@ -14,17 +14,19 @@ config = context.config
|
|||||||
# Interpret the config file for Python logging.
|
# Interpret the config file for Python logging.
|
||||||
# This line sets up loggers basically.
|
# This line sets up loggers basically.
|
||||||
fileConfig(config.config_file_name)
|
fileConfig(config.config_file_name)
|
||||||
logger = logging.getLogger('alembic.env')
|
logger = logging.getLogger("alembic.env")
|
||||||
|
|
||||||
# add your model's MetaData object here
|
# add your model's MetaData object here
|
||||||
# for 'autogenerate' support
|
# for 'autogenerate' support
|
||||||
# from myapp import mymodel
|
# from myapp import mymodel
|
||||||
# target_metadata = mymodel.Base.metadata
|
# target_metadata = mymodel.Base.metadata
|
||||||
config.set_main_option(
|
config.set_main_option(
|
||||||
'sqlalchemy.url',
|
"sqlalchemy.url",
|
||||||
str(current_app.extensions['migrate'].db.get_engine().url).replace(
|
str(current_app.extensions["migrate"].db.get_engine().url).replace(
|
||||||
'%', '%%'))
|
"%", "%%"
|
||||||
target_metadata = current_app.extensions['migrate'].db.metadata
|
),
|
||||||
|
)
|
||||||
|
target_metadata = current_app.extensions["migrate"].db.metadata
|
||||||
|
|
||||||
# other values from the config, defined by the needs of env.py,
|
# other values from the config, defined by the needs of env.py,
|
||||||
# can be acquired:
|
# can be acquired:
|
||||||
@ -33,59 +35,59 @@ target_metadata = current_app.extensions['migrate'].db.metadata
|
|||||||
|
|
||||||
|
|
||||||
def run_migrations_offline():
|
def run_migrations_offline():
|
||||||
"""Run migrations in 'offline' mode.
|
"""Run migrations in 'offline' mode.
|
||||||
|
|
||||||
This configures the context with just a URL
|
This configures the context with just a URL
|
||||||
and not an Engine, though an Engine is acceptable
|
and not an Engine, though an Engine is acceptable
|
||||||
here as well. By skipping the Engine creation
|
here as well. By skipping the Engine creation
|
||||||
we don't even need a DBAPI to be available.
|
we don't even need a DBAPI to be available.
|
||||||
|
|
||||||
Calls to context.execute() here emit the given string to the
|
Calls to context.execute() here emit the given string to the
|
||||||
script output.
|
script output.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
url = config.get_main_option("sqlalchemy.url")
|
url = config.get_main_option("sqlalchemy.url")
|
||||||
context.configure(
|
context.configure(
|
||||||
url=url, target_metadata=target_metadata, literal_binds=True
|
url=url, target_metadata=target_metadata, literal_binds=True
|
||||||
)
|
)
|
||||||
|
|
||||||
with context.begin_transaction():
|
with context.begin_transaction():
|
||||||
context.run_migrations()
|
context.run_migrations()
|
||||||
|
|
||||||
|
|
||||||
def run_migrations_online():
|
def run_migrations_online():
|
||||||
"""Run migrations in 'online' mode.
|
"""Run migrations in 'online' mode.
|
||||||
|
|
||||||
In this scenario we need to create an Engine
|
In this scenario we need to create an Engine
|
||||||
and associate a connection with the context.
|
and associate a connection with the context.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# this callback is used to prevent an auto-migration from being generated
|
# this callback is used to prevent an auto-migration from being generated
|
||||||
# when there are no changes to the schema
|
# when there are no changes to the schema
|
||||||
# reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html
|
# reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html
|
||||||
def process_revision_directives(context, revision, directives):
|
def process_revision_directives(context, revision, directives):
|
||||||
if getattr(config.cmd_opts, 'autogenerate', False):
|
if getattr(config.cmd_opts, "autogenerate", False):
|
||||||
script = directives[0]
|
script = directives[0]
|
||||||
if script.upgrade_ops.is_empty():
|
if script.upgrade_ops.is_empty():
|
||||||
directives[:] = []
|
directives[:] = []
|
||||||
logger.info('No changes in schema detected.')
|
logger.info("No changes in schema detected.")
|
||||||
|
|
||||||
connectable = current_app.extensions['migrate'].db.get_engine()
|
connectable = current_app.extensions["migrate"].db.get_engine()
|
||||||
|
|
||||||
with connectable.connect() as connection:
|
with connectable.connect() as connection:
|
||||||
context.configure(
|
context.configure(
|
||||||
connection=connection,
|
connection=connection,
|
||||||
target_metadata=target_metadata,
|
target_metadata=target_metadata,
|
||||||
process_revision_directives=process_revision_directives,
|
process_revision_directives=process_revision_directives,
|
||||||
**current_app.extensions['migrate'].configure_args
|
**current_app.extensions["migrate"].configure_args,
|
||||||
)
|
)
|
||||||
|
|
||||||
with context.begin_transaction():
|
with context.begin_transaction():
|
||||||
context.run_migrations()
|
context.run_migrations()
|
||||||
|
|
||||||
|
|
||||||
if context.is_offline_mode():
|
if context.is_offline_mode():
|
||||||
run_migrations_offline()
|
run_migrations_offline()
|
||||||
else:
|
else:
|
||||||
run_migrations_online()
|
run_migrations_online()
|
||||||
|
@ -2,17 +2,17 @@ from app import db
|
|||||||
|
|
||||||
|
|
||||||
class DistribusiFiles(db.Model):
|
class DistribusiFiles(db.Model):
|
||||||
"""Distribusi file model class for a single file in a distribusi"""
|
"""Distribusi file model class for a single file in a distribusi"""
|
||||||
|
|
||||||
__tablename__ = "distribusi_files"
|
__tablename__ = "distribusi_files"
|
||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
type = db.Column(db.String(100), nullable=True, unique=False)
|
type = db.Column(db.String(100), nullable=True, unique=False)
|
||||||
distribusi = db.Column(db.Integer, db.ForeignKey("distribusis.id"))
|
distribusi = db.Column(db.Integer, db.ForeignKey("distribusis.id"))
|
||||||
path = db.Column(db.String(4096), nullable=True, unique=False)
|
path = db.Column(db.String(4096), nullable=True, unique=False)
|
||||||
alttext = db.Column(db.String(255), nullable=True, unique=False)
|
alttext = db.Column(db.String(255), nullable=True, unique=False)
|
||||||
tags = db.Column(db.String(500), nullable=True, unique=False)
|
tags = db.Column(db.String(500), nullable=True, unique=False)
|
||||||
description = db.Column(db.String(4096), nullable=True, unique=False)
|
description = db.Column(db.String(4096), nullable=True, unique=False)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<Distribusi_File %r>" % self.path
|
return "<Distribusi_File %r>" % self.path
|
||||||
|
@ -2,18 +2,18 @@ from app import db
|
|||||||
|
|
||||||
|
|
||||||
class Distribusis(db.Model):
|
class Distribusis(db.Model):
|
||||||
"""distribusi model class for a single distribusi in distribusi-verse"""
|
"""distribusi model class for a single distribusi in distribusi-verse"""
|
||||||
|
|
||||||
__tablename__ = "distribusis"
|
__tablename__ = "distribusis"
|
||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
distribusiname = db.Column(db.String(300), nullable=False, unique=True)
|
distribusiname = db.Column(db.String(300), nullable=False, unique=True)
|
||||||
userid = db.Column(db.Integer, db.ForeignKey("users.id"))
|
userid = db.Column(db.Integer, db.ForeignKey("users.id"))
|
||||||
category = db.Column(db.String(500), nullable=True, unique=False)
|
category = db.Column(db.String(500), nullable=True, unique=False)
|
||||||
year = db.Column(db.String(9), nullable=True, unique=False)
|
year = db.Column(db.String(9), nullable=True, unique=False)
|
||||||
tags = db.Column(db.String(500), nullable=True, unique=False)
|
tags = db.Column(db.String(500), nullable=True, unique=False)
|
||||||
publictheme = db.Column(db.String(300), unique=True, nullable=True)
|
publictheme = db.Column(db.String(300), unique=True, nullable=True)
|
||||||
visible = db.Column(db.Boolean, default=False)
|
visible = db.Column(db.Boolean, default=False)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<Distribusi %r>" % self.distribusiname
|
return "<Distribusi %r>" % self.distribusiname
|
||||||
|
@ -4,18 +4,18 @@ from app import db
|
|||||||
|
|
||||||
|
|
||||||
class User(UserMixin, db.Model):
|
class User(UserMixin, db.Model):
|
||||||
"""User model class for a user in distribusi-verse"""
|
"""User model class for a user in distribusi-verse"""
|
||||||
|
|
||||||
__tablename__ = "users"
|
__tablename__ = "users"
|
||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
username = db.Column(db.String(150), unique=True, nullable=False)
|
username = db.Column(db.String(150), unique=True, nullable=False)
|
||||||
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)
|
||||||
currentdistribusi = db.Column(db.String(300), nullable=True, unique=False)
|
currentdistribusi = db.Column(db.String(300), nullable=True, unique=False)
|
||||||
resethash = db.Column(db.String(300), nullable=True, unique=True)
|
resethash = db.Column(db.String(300), nullable=True, unique=True)
|
||||||
resettime = db.Column(db.DateTime)
|
resettime = db.Column(db.DateTime)
|
||||||
admin = db.Column(db.Boolean, default=False)
|
admin = db.Column(db.Boolean, default=False)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<User %r>" % self.email
|
return "<User %r>" % self.email
|
||||||
|
105
verse/start.py
105
verse/start.py
@ -2,8 +2,14 @@
|
|||||||
|
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
from flask import (Blueprint, redirect, render_template, send_from_directory,
|
from flask import (
|
||||||
session, url_for)
|
Blueprint,
|
||||||
|
redirect,
|
||||||
|
render_template,
|
||||||
|
send_from_directory,
|
||||||
|
session,
|
||||||
|
url_for,
|
||||||
|
)
|
||||||
from flask_login import current_user, login_required, logout_user
|
from flask_login import current_user, login_required, logout_user
|
||||||
from flask_wtf.csrf import CSRFError
|
from flask_wtf.csrf import CSRFError
|
||||||
|
|
||||||
@ -31,92 +37,91 @@ APP.register_blueprint(forgot_password, url_prefix="/login/forgotpassword")
|
|||||||
APP.register_blueprint(distribusikan)
|
APP.register_blueprint(distribusikan)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@APP.before_request
|
@APP.before_request
|
||||||
def session_handler():
|
def session_handler():
|
||||||
session.permanent = True
|
session.permanent = True
|
||||||
APP.permanent_session_lifetime = timedelta(minutes=30)
|
APP.permanent_session_lifetime = timedelta(minutes=30)
|
||||||
|
|
||||||
|
|
||||||
@APP.route("/")
|
@APP.route("/")
|
||||||
def index():
|
def index():
|
||||||
UserHelper.reset_user_state()
|
UserHelper.reset_user_state()
|
||||||
uploadform = UploadForm()
|
uploadform = UploadForm()
|
||||||
distribusis = DistribusisInfo.visibledistribusis()
|
distribusis = DistribusisInfo.visibledistribusis()
|
||||||
distribusisindex = {}
|
distribusisindex = {}
|
||||||
for distribusi in distribusis:
|
for distribusi in distribusis:
|
||||||
user = User.query.filter_by(id=distribusi.userid).first()
|
user = User.query.filter_by(id=distribusi.userid).first()
|
||||||
singledistribusi = {
|
singledistribusi = {
|
||||||
"username": user.username,
|
"username": user.username,
|
||||||
"publictheme": distribusi.publictheme,
|
"publictheme": distribusi.publictheme,
|
||||||
"category": distribusi.category,
|
"category": distribusi.category,
|
||||||
"year": distribusi.year,
|
"year": distribusi.year,
|
||||||
"tags": distribusi.tags.split(","),
|
"tags": distribusi.tags.split(","),
|
||||||
}
|
}
|
||||||
distribusisindex[distribusi.distribusiname] = singledistribusi
|
distribusisindex[distribusi.distribusiname] = singledistribusi
|
||||||
years = uploadform.year.choices
|
years = uploadform.year.choices
|
||||||
categories = uploadform.category.choices
|
categories = uploadform.category.choices
|
||||||
adminuser = isadminuser()
|
adminuser = is_adminuser()
|
||||||
template = render_template(
|
template = render_template(
|
||||||
"base/index.html",
|
"base/index.html",
|
||||||
distribusisindex=distribusisindex,
|
distribusisindex=distribusisindex,
|
||||||
years=years,
|
years=years,
|
||||||
categories=categories,
|
categories=categories,
|
||||||
adminuser=adminuser,
|
adminuser=adminuser,
|
||||||
)
|
)
|
||||||
return template
|
return template
|
||||||
|
|
||||||
|
|
||||||
@APP.route("/help")
|
@APP.route("/help")
|
||||||
def help():
|
def help():
|
||||||
return render_template("base/help.html")
|
return render_template("base/help.html")
|
||||||
|
|
||||||
|
|
||||||
@APP.route("/publicthemes/<path>")
|
@APP.route("/publicthemes/<path>")
|
||||||
def publicthemes(path):
|
def publicthemes(path):
|
||||||
distribusi = Distribusis.query.filter_by(distribusiname=path).first()
|
distribusi = Distribusis.query.filter_by(distribusiname=path).first()
|
||||||
publicthemefolder = f"publicthemes/{distribusi.distribusiname}/"
|
publicthemefolder = f"publicthemes/{distribusi.distribusiname}/"
|
||||||
cssfile = f"{publicthemefolder}/{distribusi.publictheme}.css"
|
cssfile = f"{publicthemefolder}/{distribusi.publictheme}.css"
|
||||||
return send_from_directory("themes", cssfile, as_attachment=True)
|
return send_from_directory("themes", cssfile, as_attachment=True)
|
||||||
|
|
||||||
|
|
||||||
@APP.route("/stash")
|
@APP.route("/stash")
|
||||||
def shortstashurl():
|
def shortstashurl():
|
||||||
return redirect(url_for("index"))
|
return redirect(url_for("index"))
|
||||||
|
|
||||||
|
|
||||||
@APP.route("/admin", methods=["GET", "POST"])
|
@APP.route("/admin", methods=["GET", "POST"])
|
||||||
@login_required
|
@login_required
|
||||||
def admin():
|
def admin():
|
||||||
if not isadminuser():
|
if not is_adminuser():
|
||||||
return redirect(url_for("index"))
|
return redirect(url_for("index"))
|
||||||
return AdminPage()
|
return AdminPage()
|
||||||
|
|
||||||
|
|
||||||
@APP.route("/logout")
|
@APP.route("/logout")
|
||||||
@login_required
|
@login_required
|
||||||
def logout():
|
def logout():
|
||||||
logout_user()
|
logout_user()
|
||||||
return redirect(url_for("index"))
|
return redirect(url_for("index"))
|
||||||
|
|
||||||
|
|
||||||
@APP.errorhandler(CSRFError)
|
@APP.errorhandler(CSRFError)
|
||||||
def handle_csrf_error(e):
|
def handle_csrf_error(e):
|
||||||
return render_template("csrf_error.html", reason=e.description), 400
|
return render_template("csrf_error.html", reason=e.description), 400
|
||||||
|
|
||||||
|
|
||||||
@login_manager.user_loader
|
@login_manager.user_loader
|
||||||
def load_user(user_id):
|
def load_user(user_id):
|
||||||
return User.query.get(int(user_id))
|
return User.query.get(int(user_id))
|
||||||
|
|
||||||
|
|
||||||
def isadminuser():
|
def is_adminuser():
|
||||||
if not current_user.is_authenticated:
|
if not current_user.is_authenticated:
|
||||||
return False
|
return False
|
||||||
user = User.query.filter_by(email=current_user.email).first()
|
user = User.query.filter_by(email=current_user.email).first()
|
||||||
return user.admin
|
return user.admin
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
APP.debug = True
|
APP.debug = True
|
||||||
APP.run(port=5000)
|
APP.run(port=5000)
|
||||||
|
@ -4,10 +4,10 @@ from uuid import uuid1
|
|||||||
from flask import Blueprint, render_template
|
from flask import Blueprint, render_template
|
||||||
from flask_mail import Mail, Message
|
from flask_mail import Mail, Message
|
||||||
from sqlalchemy.exc import (
|
from sqlalchemy.exc import (
|
||||||
DatabaseError,
|
DatabaseError,
|
||||||
DataError,
|
DataError,
|
||||||
InterfaceError,
|
InterfaceError,
|
||||||
InvalidRequestError,
|
InvalidRequestError,
|
||||||
)
|
)
|
||||||
|
|
||||||
from app import db, get_app
|
from app import db, get_app
|
||||||
@ -16,57 +16,57 @@ from models.user_model import User
|
|||||||
|
|
||||||
mail = Mail(get_app())
|
mail = Mail(get_app())
|
||||||
forgot_password = Blueprint(
|
forgot_password = Blueprint(
|
||||||
"forgotpassword",
|
"forgotpassword",
|
||||||
__name__,
|
__name__,
|
||||||
template_folder="templates/statuspengguna",
|
template_folder="templates/statuspengguna",
|
||||||
static_folder="static",
|
static_folder="static",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@forgot_password.route("/", methods=["GET", "POST"])
|
@forgot_password.route("/", methods=["GET", "POST"])
|
||||||
def forgotpassword():
|
def forgotpassword():
|
||||||
return ForgotPassword(mail)
|
return ForgotPassword(mail)
|
||||||
|
|
||||||
|
|
||||||
def ForgotPassword(mail):
|
def ForgotPassword(mail):
|
||||||
forgotpasswordform = ForgotPasswordForm()
|
forgotpasswordform = ForgotPasswordForm()
|
||||||
if forgotpasswordform.validate_on_submit():
|
if forgotpasswordform.validate_on_submit():
|
||||||
user = User.query.filter_by(
|
user = User.query.filter_by(
|
||||||
email=forgotpasswordform.email.data
|
email=forgotpasswordform.email.data
|
||||||
).first()
|
).first()
|
||||||
if user is not None:
|
if user is not None:
|
||||||
resethash = AddResetPasswordHash(user, forgotpasswordform)
|
resethash = AddResetPasswordHash(user, forgotpasswordform)
|
||||||
ResetPassWordMessage(user, resethash, mail)
|
ResetPassWordMessage(user, resethash, mail)
|
||||||
forgotpasswordform.email.errors.append(
|
forgotpasswordform.email.errors.append(
|
||||||
f"""If {forgotpasswordform.email.data} exists, an email is send with
|
f"""If {forgotpasswordform.email.data} exists, an email is send with
|
||||||
a password reset link. (If your inbox doesn't
|
a password reset link. (If your inbox doesn't
|
||||||
contain any new mail, please check your spam folder.)"""
|
contain any new mail, please check your spam folder.)"""
|
||||||
)
|
)
|
||||||
return render_template(
|
return render_template(
|
||||||
"forgotpassword.html", forgotpasswordform=forgotpasswordform
|
"forgotpassword.html", forgotpasswordform=forgotpasswordform
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def AddResetPasswordHash(user, forgotpasswordform):
|
def AddResetPasswordHash(user, forgotpasswordform):
|
||||||
resethash = uuid1().hex
|
resethash = uuid1().hex
|
||||||
try:
|
try:
|
||||||
user.resettime = datetime.now()
|
user.resettime = datetime.now()
|
||||||
user.resethash = resethash
|
user.resethash = resethash
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
except (InvalidRequestError, DataError, InterfaceError, DatabaseError):
|
except (InvalidRequestError, DataError, InterfaceError, DatabaseError):
|
||||||
forgotpasswordform.email.errors.append("Something went wrong!")
|
forgotpasswordform.email.errors.append("Something went wrong!")
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
return resethash
|
return resethash
|
||||||
|
|
||||||
|
|
||||||
def ResetPassWordMessage(user, resethash, mail):
|
def ResetPassWordMessage(user, resethash, mail):
|
||||||
msg = Message(
|
msg = Message(
|
||||||
"Distribusiverse Forgotten Password ",
|
"Distribusiverse Forgotten Password ",
|
||||||
sender=("Distribusiverse mailer", "test@this.com"),
|
sender=("Distribusiverse mailer", "test@this.com"),
|
||||||
recipients=[user.email],
|
recipients=[user.email],
|
||||||
)
|
)
|
||||||
msg.html = f"""{user.username} has requested a password reset for
|
msg.html = f"""{user.username} has requested a password reset for
|
||||||
Distribusiverse.<br><hr>
|
Distribusiverse.<br><hr>
|
||||||
<a href='http://localhost:5000/resetpassword/{resethash}'>Click here to
|
<a href='http://localhost:5000/resetpassword/{resethash}'>Click here to
|
||||||
reset your password.</a>"""
|
reset your password.</a>"""
|
||||||
mail.send(msg)
|
mail.send(msg)
|
||||||
|
@ -3,10 +3,10 @@ import os
|
|||||||
from flask import flash
|
from flask import flash
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from sqlalchemy.exc import (
|
from sqlalchemy.exc import (
|
||||||
DatabaseError,
|
DatabaseError,
|
||||||
DataError,
|
DataError,
|
||||||
InterfaceError,
|
InterfaceError,
|
||||||
InvalidRequestError,
|
InvalidRequestError,
|
||||||
)
|
)
|
||||||
|
|
||||||
from app import db
|
from app import db
|
||||||
@ -16,68 +16,68 @@ from models.user_model import User
|
|||||||
|
|
||||||
|
|
||||||
class UserHelper:
|
class UserHelper:
|
||||||
def is_zip_uploaded(distribusiname):
|
def is_zip_uploaded(distribusiname):
|
||||||
userfolder = os.path.join("stash", distribusiname)
|
userfolder = os.path.join("stash", distribusiname)
|
||||||
if os.path.exists(userfolder):
|
if os.path.exists(userfolder):
|
||||||
zipfilename = "{}.zip".format(distribusiname)
|
zipfilename = "{}.zip".format(distribusiname)
|
||||||
if os.path.exists(os.path.join(userfolder, zipfilename)):
|
if os.path.exists(os.path.join(userfolder, zipfilename)):
|
||||||
print("folder with zipfile found, file uploaded")
|
print("folder with zipfile found, file uploaded")
|
||||||
return True
|
return True
|
||||||
print("distribusi folder has no zipfile")
|
print("distribusi folder has no zipfile")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def is_distribusi_live(distribusiname):
|
def is_distribusi_live(distribusiname):
|
||||||
userfolder = os.path.join("stash", distribusiname)
|
userfolder = os.path.join("stash", distribusiname)
|
||||||
if os.path.exists(userfolder):
|
if os.path.exists(userfolder):
|
||||||
zipfilename = "{}.zip".format(distribusiname)
|
zipfilename = "{}.zip".format(distribusiname)
|
||||||
if os.path.exists(os.path.join(userfolder, zipfilename)):
|
if os.path.exists(os.path.join(userfolder, zipfilename)):
|
||||||
print("folder with zipfile found, file uploaded")
|
print("folder with zipfile found, file uploaded")
|
||||||
return False
|
return False
|
||||||
if len(os.listdir(userfolder)) > 0:
|
if len(os.listdir(userfolder)) > 0:
|
||||||
return True
|
return True
|
||||||
print("distribusi folder is empty")
|
print("distribusi folder is empty")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def is_css_selected(distribusiname):
|
def is_css_selected(distribusiname):
|
||||||
userfolder = os.path.join("themes/userthemes", distribusiname)
|
userfolder = os.path.join("themes/userthemes", distribusiname)
|
||||||
if os.path.exists(userfolder):
|
if os.path.exists(userfolder):
|
||||||
for file in os.listdir(userfolder):
|
for file in os.listdir(userfolder):
|
||||||
if file.endswith(".css"):
|
if file.endswith(".css"):
|
||||||
return True
|
return True
|
||||||
print("distribusi folder has no css file")
|
print("distribusi folder has no css file")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def has_distribusi():
|
def has_distribusi():
|
||||||
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()
|
distribusi = Distribusis.query.filter_by(userid=user.id).first()
|
||||||
if distribusi is None:
|
if distribusi is None:
|
||||||
print("no distribusi found")
|
print("no distribusi found")
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def current_distribusi():
|
def current_distribusi():
|
||||||
user = User.query.filter_by(email=current_user.email).first()
|
user = User.query.filter_by(email=current_user.email).first()
|
||||||
if user.currentdistribusi is None:
|
if user.currentdistribusi is None:
|
||||||
return "None"
|
return "None"
|
||||||
return user.currentdistribusi
|
return user.currentdistribusi
|
||||||
|
|
||||||
def reset_user_state():
|
def reset_user_state():
|
||||||
"""reset user state upon visiting index, so that distribusi workflow can
|
"""reset user state upon visiting index, so that distribusi workflow can
|
||||||
be done correctly"""
|
be done correctly"""
|
||||||
if not current_user.is_authenticated:
|
if not current_user.is_authenticated:
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
user = User.query.filter_by(email=current_user.email).first()
|
user = User.query.filter_by(email=current_user.email).first()
|
||||||
user.currentdistribusi = None
|
user.currentdistribusi = None
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
except (InvalidRequestError, DataError, InterfaceError, DatabaseError):
|
except (InvalidRequestError, DataError, InterfaceError, DatabaseError):
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
flash("An error occured !", "danger")
|
flash("An error occured !", "danger")
|
||||||
|
|
||||||
def distribusi_limit_reached():
|
def distribusi_limit_reached():
|
||||||
user = User.query.filter_by(email=current_user.email).first()
|
user = User.query.filter_by(email=current_user.email).first()
|
||||||
distribusiamount = len(DistribusisInfo.getuserdistribusis(user.email))
|
distribusiamount = len(DistribusisInfo.getuserdistribusis(user.email))
|
||||||
if distribusiamount > 19:
|
if distribusiamount > 19:
|
||||||
print("user already has 20 distribusis")
|
print("user already has 20 distribusis")
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
from flask import (
|
from flask import (
|
||||||
Blueprint,
|
Blueprint,
|
||||||
abort,
|
abort,
|
||||||
flash,
|
flash,
|
||||||
redirect,
|
redirect,
|
||||||
render_template,
|
render_template,
|
||||||
request,
|
request,
|
||||||
url_for,
|
url_for,
|
||||||
)
|
)
|
||||||
from flask_bcrypt import check_password_hash
|
from flask_bcrypt import check_password_hash
|
||||||
from flask_login import login_user
|
from flask_login import login_user
|
||||||
@ -14,39 +14,39 @@ from forms.loginform import LoginForm
|
|||||||
from models.user_model import User
|
from models.user_model import User
|
||||||
|
|
||||||
login_section = Blueprint(
|
login_section = Blueprint(
|
||||||
"login",
|
"login",
|
||||||
__name__,
|
__name__,
|
||||||
template_folder="templates/statuspengguna",
|
template_folder="templates/statuspengguna",
|
||||||
static_folder="static",
|
static_folder="static",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_section.route("/", methods=["GET", "POST"])
|
@login_section.route("/", methods=["GET", "POST"])
|
||||||
def login():
|
def login():
|
||||||
return LoginUser()
|
return LoginUser()
|
||||||
|
|
||||||
|
|
||||||
def LoginUser():
|
def LoginUser():
|
||||||
loginform = LoginForm()
|
loginform = LoginForm()
|
||||||
if loginform.validate_on_submit():
|
if loginform.validate_on_submit():
|
||||||
try:
|
try:
|
||||||
user = User.query.filter_by(email=loginform.email.data).first()
|
user = User.query.filter_by(email=loginform.email.data).first()
|
||||||
if user is None:
|
if user is None:
|
||||||
loginform.password.errors.append("Invalid email or password!")
|
loginform.password.errors.append("Invalid email or password!")
|
||||||
return render_template("login.html", loginform=loginform)
|
return render_template("login.html", loginform=loginform)
|
||||||
if check_password_hash(user.password, loginform.password.data):
|
if check_password_hash(user.password, loginform.password.data):
|
||||||
login_user(user)
|
login_user(user)
|
||||||
flash("Logged in successfully.", "success")
|
flash("Logged in successfully.", "success")
|
||||||
next = request.args.get("next")
|
next = request.args.get("next")
|
||||||
if next is not None and not is_safe_url(next): # noqa: F821
|
if next is not None and not is_safe_url(next): # noqa: F821
|
||||||
print(next)
|
print(next)
|
||||||
return abort(400)
|
return abort(400)
|
||||||
print("index")
|
print("index")
|
||||||
return redirect(next or url_for("index"))
|
return redirect(next or url_for("index"))
|
||||||
else:
|
else:
|
||||||
flash("Invalid email or password!", "danger")
|
flash("Invalid email or password!", "danger")
|
||||||
loginform.password.errors.append("Invalid email or password!")
|
loginform.password.errors.append("Invalid email or password!")
|
||||||
return render_template("login.html", loginform=loginform)
|
return render_template("login.html", loginform=loginform)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
flash(e, "danger")
|
flash(e, "danger")
|
||||||
return render_template("login.html", loginform=loginform)
|
return render_template("login.html", loginform=loginform)
|
||||||
|
@ -2,11 +2,11 @@ from flask import Blueprint, flash, redirect, render_template, url_for
|
|||||||
from flask_bcrypt import generate_password_hash
|
from flask_bcrypt import generate_password_hash
|
||||||
from flask_login import login_user
|
from flask_login import login_user
|
||||||
from sqlalchemy.exc import (
|
from sqlalchemy.exc import (
|
||||||
DatabaseError,
|
DatabaseError,
|
||||||
DataError,
|
DataError,
|
||||||
IntegrityError,
|
IntegrityError,
|
||||||
InterfaceError,
|
InterfaceError,
|
||||||
InvalidRequestError,
|
InvalidRequestError,
|
||||||
)
|
)
|
||||||
from werkzeug.routing import BuildError
|
from werkzeug.routing import BuildError
|
||||||
|
|
||||||
@ -15,64 +15,64 @@ from forms.registerform import RegisterForm
|
|||||||
from models.user_model import User
|
from models.user_model import User
|
||||||
|
|
||||||
register_user = Blueprint(
|
register_user = Blueprint(
|
||||||
"register",
|
"register",
|
||||||
__name__,
|
__name__,
|
||||||
template_folder="templates/statuspengguna",
|
template_folder="templates/statuspengguna",
|
||||||
static_folder="static",
|
static_folder="static",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@register_user.route("/", methods=["GET", "POST"])
|
@register_user.route("/", methods=["GET", "POST"])
|
||||||
def register():
|
def register():
|
||||||
return RegisterUser()
|
return RegisterUser()
|
||||||
|
|
||||||
|
|
||||||
def RegisterUser():
|
def RegisterUser():
|
||||||
registerform = RegisterForm()
|
registerform = RegisterForm()
|
||||||
if registerform.validate_on_submit():
|
if registerform.validate_on_submit():
|
||||||
try:
|
try:
|
||||||
username = registerform.username.data
|
username = registerform.username.data
|
||||||
email = registerform.email.data
|
email = registerform.email.data
|
||||||
password = registerform.confirmpassword.data
|
password = registerform.confirmpassword.data
|
||||||
|
|
||||||
newuser = User(
|
newuser = User(
|
||||||
username=username,
|
username=username,
|
||||||
email=email,
|
email=email,
|
||||||
password=generate_password_hash(password),
|
password=generate_password_hash(password),
|
||||||
)
|
)
|
||||||
|
|
||||||
db.session.add(newuser)
|
db.session.add(newuser)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash("Account Succesfully created", "success")
|
flash("Account Succesfully created", "success")
|
||||||
login_user(newuser)
|
login_user(newuser)
|
||||||
return redirect(url_for("index"))
|
return redirect(url_for("index"))
|
||||||
|
|
||||||
except InvalidRequestError:
|
except InvalidRequestError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
registerform.email.errors.append("Something went wrong!")
|
registerform.email.errors.append("Something went wrong!")
|
||||||
flash("Something went wrong!", "danger")
|
flash("Something went wrong!", "danger")
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
registerform.email.errors.append("User already exists!")
|
registerform.email.errors.append("User already exists!")
|
||||||
flash("User already exists!", "warning")
|
flash("User already exists!", "warning")
|
||||||
except DataError:
|
except DataError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
registerform.email.errors.append("Invalid Entry")
|
registerform.email.errors.append("Invalid Entry")
|
||||||
flash("Invalid Entry", "warning")
|
flash("Invalid Entry", "warning")
|
||||||
except InterfaceError:
|
except InterfaceError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
registerform.email.errors.append(
|
registerform.email.errors.append(
|
||||||
"Error connecting to the database"
|
"Error connecting to the database"
|
||||||
)
|
)
|
||||||
flash("Error connecting to the database", "danger")
|
flash("Error connecting to the database", "danger")
|
||||||
except DatabaseError:
|
except DatabaseError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
registerform.email.errors.append(
|
registerform.email.errors.append(
|
||||||
"Error connecting to the database"
|
"Error connecting to the database"
|
||||||
)
|
)
|
||||||
flash("Error connecting to the database", "danger")
|
flash("Error connecting to the database", "danger")
|
||||||
except BuildError:
|
except BuildError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
registerform.email.errors.append("Unknown error occured!")
|
registerform.email.errors.append("Unknown error occured!")
|
||||||
flash("An error occured !", "danger")
|
flash("An error occured !", "danger")
|
||||||
return render_template("register.html", registerform=registerform)
|
return render_template("register.html", registerform=registerform)
|
||||||
|
@ -4,11 +4,11 @@ from flask import Blueprint, flash, redirect, render_template, url_for
|
|||||||
from flask_bcrypt import generate_password_hash
|
from flask_bcrypt import generate_password_hash
|
||||||
from flask_login import login_user
|
from flask_login import login_user
|
||||||
from sqlalchemy.exc import (
|
from sqlalchemy.exc import (
|
||||||
DatabaseError,
|
DatabaseError,
|
||||||
DataError,
|
DataError,
|
||||||
IntegrityError,
|
IntegrityError,
|
||||||
InterfaceError,
|
InterfaceError,
|
||||||
InvalidRequestError,
|
InvalidRequestError,
|
||||||
)
|
)
|
||||||
from werkzeug.routing import BuildError
|
from werkzeug.routing import BuildError
|
||||||
|
|
||||||
@ -17,74 +17,74 @@ from forms.resetpasswordform import ResetPasswordForm
|
|||||||
from models.user_model import User
|
from models.user_model import User
|
||||||
|
|
||||||
reset_password = Blueprint(
|
reset_password = Blueprint(
|
||||||
"reset_password",
|
"reset_password",
|
||||||
__name__,
|
__name__,
|
||||||
template_folder="templates/statuspengguna",
|
template_folder="templates/statuspengguna",
|
||||||
static_folder="static",
|
static_folder="static",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@reset_password.route("/resetpassword/<path>", methods=["GET", "POST"])
|
@reset_password.route("/resetpassword/<path>", methods=["GET", "POST"])
|
||||||
def resetpassword(path):
|
def resetpassword(path):
|
||||||
return ResetPassword(path)
|
return ResetPassword(path)
|
||||||
|
|
||||||
|
|
||||||
def ResetPassword(path):
|
def ResetPassword(path):
|
||||||
linkvalid = False
|
linkvalid = False
|
||||||
user = User.query.filter_by(resethash=path).first()
|
user = User.query.filter_by(resethash=path).first()
|
||||||
if user is None:
|
if user is None:
|
||||||
return redirect(url_for("index"))
|
return redirect(url_for("index"))
|
||||||
timepassed = datetime.now() - user.resettime
|
timepassed = datetime.now() - user.resettime
|
||||||
if timepassed.days < 1:
|
if timepassed.days < 1:
|
||||||
linkvalid = True
|
linkvalid = True
|
||||||
|
|
||||||
resetpasswordform = ResetPasswordForm()
|
resetpasswordform = ResetPasswordForm()
|
||||||
if resetpasswordform.validate_on_submit():
|
if resetpasswordform.validate_on_submit():
|
||||||
return ResetUserPasswordInDB(user, resetpasswordform)
|
return ResetUserPasswordInDB(user, resetpasswordform)
|
||||||
return render_template(
|
return render_template(
|
||||||
"resetpassword.html",
|
"resetpassword.html",
|
||||||
resetpasswordform=resetpasswordform,
|
resetpasswordform=resetpasswordform,
|
||||||
path=path,
|
path=path,
|
||||||
linkvalid=linkvalid,
|
linkvalid=linkvalid,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def ResetUserPasswordInDB(user, resetpasswordform):
|
def ResetUserPasswordInDB(user, resetpasswordform):
|
||||||
try:
|
try:
|
||||||
newpassword = resetpasswordform.confirmpassword.data
|
newpassword = resetpasswordform.confirmpassword.data
|
||||||
user.password = generate_password_hash(newpassword)
|
user.password = generate_password_hash(newpassword)
|
||||||
user.resethash = None
|
user.resethash = None
|
||||||
user.resettime = None
|
user.resettime = None
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
flash("Password Succesfully updated", "success")
|
flash("Password Succesfully updated", "success")
|
||||||
login_user(user)
|
login_user(user)
|
||||||
return redirect(url_for("index"))
|
return redirect(url_for("index"))
|
||||||
|
|
||||||
except InvalidRequestError:
|
except InvalidRequestError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
resetpasswordform.email.errors.append("Something went wrong!")
|
resetpasswordform.email.errors.append("Something went wrong!")
|
||||||
flash("Something went wrong!", "danger")
|
flash("Something went wrong!", "danger")
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
resetpasswordform.email.errors.append("User already exists!")
|
resetpasswordform.email.errors.append("User already exists!")
|
||||||
flash("User already exists!", "warning")
|
flash("User already exists!", "warning")
|
||||||
except DataError:
|
except DataError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
resetpasswordform.email.errors.append("Invalid Entry")
|
resetpasswordform.email.errors.append("Invalid Entry")
|
||||||
flash("Invalid Entry", "warning")
|
flash("Invalid Entry", "warning")
|
||||||
except InterfaceError:
|
except InterfaceError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
resetpasswordform.email.errors.append(
|
resetpasswordform.email.errors.append(
|
||||||
"Error connecting to the database"
|
"Error connecting to the database"
|
||||||
)
|
)
|
||||||
flash("Error connecting to the database", "danger")
|
flash("Error connecting to the database", "danger")
|
||||||
except DatabaseError:
|
except DatabaseError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
resetpasswordform.email.errors.append(
|
resetpasswordform.email.errors.append(
|
||||||
"Error connecting to the database"
|
"Error connecting to the database"
|
||||||
)
|
)
|
||||||
flash("Error connecting to the database", "danger")
|
flash("Error connecting to the database", "danger")
|
||||||
except BuildError:
|
except BuildError:
|
||||||
db.session.rollback()
|
db.session.rollback()
|
||||||
resetpasswordform.email.errors.append("Unknown error occured!")
|
resetpasswordform.email.errors.append("Unknown error occured!")
|
||||||
flash("An error occured !", "danger")
|
flash("An error occured !", "danger")
|
||||||
|
Loading…
Reference in New Issue
Block a user