Browse Source

leave no file untouched

main
crunk 7 months ago
parent
commit
bd519d6925
  1. 9
      verse/adminpage.py
  2. 5
      verse/admintool.py
  3. 6
      verse/app.py
  4. 3
      verse/deploydb.py
  5. 46
      verse/distribusikan/distribusikan.py
  6. 9
      verse/distribusikan/distribusiselector.py
  7. 1
      verse/distribusikan/distribusisinfo.py
  8. 14
      verse/distribusikan/distribusiworkflow.py
  9. 11
      verse/distribusikan/editor.py
  10. 2
      verse/distribusikan/templates/distribusikan/distribusi.html
  11. 0
      verse/distribusikan/templates/distribusikan/distribusiworkflow/editcss.html
  12. 2
      verse/distribusikan/templates/distribusikan/distribusiworkflow/launch.html
  13. 2
      verse/distribusikan/templates/distribusikan/distribusiworkflow/selector.html
  14. 4
      verse/distribusikan/templates/distribusikan/distribusiworkflow/theme.html
  15. 2
      verse/distribusikan/templates/distribusikan/distribusiworkflow/upload.html
  16. 2
      verse/distribusikan/templates/distribusikan/editor.html
  17. 3
      verse/distribusikan/themeselector.py
  18. 9
      verse/distribusikan/upload.py
  19. 9
      verse/distribusikan/uploadpage.py
  20. 3
      verse/forms/uploadform.py
  21. 3
      verse/models/usermodel.py
  22. 83
      verse/start.py
  23. 0
      verse/statuspengguna/__init__.py
  24. 24
      verse/statuspengguna/forgotpassword.py
  25. 9
      verse/statuspengguna/helper.py
  26. 19
      verse/statuspengguna/loginuser.py
  27. 21
      verse/statuspengguna/registeruser.py
  28. 20
      verse/statuspengguna/resetpassword.py
  29. 69
      verse/statuspengguna/static/css/dropdown.css
  30. 50
      verse/statuspengguna/static/css/editor.css
  31. 53
      verse/statuspengguna/static/css/selector.css
  32. 286
      verse/statuspengguna/static/css/style.css
  33. 6
      verse/statuspengguna/static/icons/about.txt
  34. BIN
      verse/statuspengguna/static/icons/android-chrome-192x192.png
  35. BIN
      verse/statuspengguna/static/icons/android-chrome-512x512.png
  36. BIN
      verse/statuspengguna/static/icons/apple-touch-icon.png
  37. BIN
      verse/statuspengguna/static/icons/favicon-16x16.png
  38. BIN
      verse/statuspengguna/static/icons/favicon-32x32.png
  39. BIN
      verse/statuspengguna/static/icons/favicon.ico
  40. 1
      verse/statuspengguna/static/icons/site.webmanifest
  41. 92
      verse/statuspengguna/static/js/dropdown.js
  42. 19
      verse/statuspengguna/static/js/editorupdate.js
  43. 25
      verse/statuspengguna/static/js/script.js
  44. 75
      verse/statuspengguna/static/svg/arrow_1.svg
  45. 12
      verse/statuspengguna/static/svg/arrow_2.svg
  46. 12
      verse/statuspengguna/static/svg/arrow_3.svg
  47. 5
      verse/statuspengguna/templates/statuspengguna/forgotpassword.html
  48. 6
      verse/statuspengguna/templates/statuspengguna/login.html
  49. 4
      verse/statuspengguna/templates/statuspengguna/register.html
  50. 2
      verse/statuspengguna/templates/statuspengguna/resetpassword.html
  51. 2
      verse/templates/base/admin.html
  52. 0
      verse/templates/base/base.html
  53. 0
      verse/templates/base/filtermenu.html
  54. 2
      verse/templates/base/help.html
  55. 4
      verse/templates/base/index.html

9
verse/adminpage.py

@ -1,15 +1,16 @@
import os import os
import shutil import shutil
from app import db
from distribusisinfo import DistribusisInfo
from flask import render_template from flask import render_template
from sqlalchemy.exc import (DatabaseError, DataError, InterfaceError,
InvalidRequestError)
from app import db
from distribusikan.distribusisinfo import DistribusisInfo
from forms.admindistribusiform import AdminDistribusiForm from forms.admindistribusiform import AdminDistribusiForm
from forms.adminuserform import AdminUserForm from forms.adminuserform import AdminUserForm
from models.distribusimodel import Distribusis from models.distribusimodel import Distribusis
from models.usermodel import User from models.usermodel import User
from sqlalchemy.exc import (DatabaseError, DataError, InterfaceError,
InvalidRequestError)
def AdminPage(): def AdminPage():

5
verse/admintool.py

@ -1,10 +1,11 @@
import sys import sys
from sqlalchemy.exc import (DatabaseError, DataError, InterfaceError,
InvalidRequestError)
from app import create_app, db from app import create_app, db
from models.distribusimodel import Distribusis # noqa: F401 from models.distribusimodel import Distribusis # noqa: F401
from models.usermodel import User # noqa: F401 from models.usermodel import User # noqa: F401
from sqlalchemy.exc import (DatabaseError, DataError, InterfaceError,
InvalidRequestError)
def admintool(): def admintool():

6
verse/app.py

@ -16,7 +16,7 @@ login_manager = LoginManager()
def create_app(): def create_app():
APP.secret_key = "secret-key" 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
@ -59,6 +59,10 @@ def settings():
return APP return APP
def get_app():
return APP
def settings_from_file(): def settings_from_file():
settings = {} settings = {}
if os.path.isfile("settings_development.toml"): if os.path.isfile("settings_development.toml"):

3
verse/deploydb.py

@ -1,7 +1,8 @@
def deploy(): def deploy():
"""Run deployment of database.""" """Run deployment of database."""
from app import create_app, db
from flask_migrate import init, migrate, stamp, upgrade from flask_migrate import init, migrate, stamp, upgrade
from app import create_app, db
from models.distribusimodel import Distribusis # noqa: F401 from models.distribusimodel import Distribusis # 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.usermodel import User # noqa: F401 from models.usermodel import User # noqa: F401

46
verse/distribusikan/distribusikan.py

@ -0,0 +1,46 @@
from flask import Blueprint
from flask_login import login_required
from distribusikan.distribusiselector import DistribusiSelector
# Distribusi Information
from distribusikan.distribusisinfo import DistribusisInfo
from distribusikan.distribusiworkflow import DistribusiWorkflow
from distribusikan.editor import Editor
from distribusikan.themeselector import ThemeSelector
from distribusikan.uploadpage import UploadPage
distribusikan = Blueprint(
"distribusikan",
__name__,
template_folder="templates/distribusikan",
static_folder="static",
)
@distribusikan.route("/distribusi", methods=["GET", "POST"])
@login_required
def distribusi():
return DistribusiWorkflow()
@distribusikan.route("/upload", methods=["POST"])
@login_required
def upload():
return UploadPage()
@distribusikan.route("/theme", methods=["GET", "POST"])
@login_required
def theme():
return ThemeSelector()
@distribusikan.route("/editor", methods=["GET", "POST"])
@login_required
def editor():
return Editor()
@distribusikan.route("/selector", methods=["GET", "POST"])
@login_required
def selector():
return DistribusiSelector()

9
verse/distribusiselector.py → verse/distribusikan/distribusiselector.py

@ -1,10 +1,13 @@
import os import os
import shutil import shutil
from app import db
from distribusisinfo import DistribusisInfo
from flask import flash, render_template from flask import flash, render_template
from flask_login import current_user from flask_login import current_user
from sqlalchemy.exc import (DatabaseError, DataError, InterfaceError,
InvalidRequestError)
from app import db
from distribusikan.distribusisinfo import DistribusisInfo
from forms.distribusiform import DistribusiForm from forms.distribusiform import DistribusiForm
from forms.publicthemeform import PublicThemeForm from forms.publicthemeform import PublicThemeForm
from forms.selectorform import SelectorForm from forms.selectorform import SelectorForm
@ -12,8 +15,6 @@ from forms.themeform import ThemeForm
from forms.uploadform import UploadForm from forms.uploadform import UploadForm
from models.distribusimodel import Distribusis from models.distribusimodel import Distribusis
from models.usermodel import User from models.usermodel import User
from sqlalchemy.exc import (DatabaseError, DataError, InterfaceError,
InvalidRequestError)
# UserPengguna # UserPengguna
from statuspengguna.helper import UserHelper from statuspengguna.helper import UserHelper

1
verse/distribusisinfo.py → verse/distribusikan/distribusisinfo.py

@ -1,4 +1,5 @@
from flask_login import current_user from flask_login import current_user
from models.distribusimodel import Distribusis from models.distribusimodel import Distribusis
from models.usermodel import User from models.usermodel import User

14
verse/distribusiworkflow.py → verse/distribusikan/distribusiworkflow.py

@ -2,13 +2,17 @@ import os
import shutil import shutil
import zipfile import zipfile
from app import db
# Tada! # Tada!
from distribusi.cli import build_argparser from distribusi.cli import build_argparser
from distribusiselector import SelectorVisible from distribusi.distribusi import distribusify
from distribusisinfo import DistribusisInfo
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 (DatabaseError, DataError, InterfaceError,
InvalidRequestError)
from app import db
from distribusikan.distribusiselector import SelectorVisible
from distribusikan.distribusisinfo import DistribusisInfo
from forms.distribusiform import DistribusiForm from forms.distribusiform import DistribusiForm
from forms.publicthemeform import PublicThemeForm from forms.publicthemeform import PublicThemeForm
from forms.selectorform import SelectorForm from forms.selectorform import SelectorForm
@ -17,13 +21,9 @@ from forms.themeform import ThemeForm
from forms.uploadform import UploadForm from forms.uploadform import UploadForm
from models.distribusimodel import Distribusis from models.distribusimodel import Distribusis
from models.usermodel import User from models.usermodel import User
from sqlalchemy.exc import (DatabaseError, DataError, InterfaceError,
InvalidRequestError)
# UserPengguna # UserPengguna
from statuspengguna.helper import UserHelper from statuspengguna.helper import UserHelper
from distribusi.distribusi import distribusify
def DistribusiWorkflow(): def DistribusiWorkflow():
distribusiform = DistribusiForm() distribusiform = DistribusiForm()

11
verse/editor.py → verse/distribusikan/editor.py

@ -2,10 +2,14 @@ import os
import shutil import shutil
import bleach import bleach
from app import db
from bleach_allowlist import all_styles from bleach_allowlist import all_styles
from distribusisinfo import DistribusisInfo
from flask import render_template from flask import render_template
from sqlalchemy.exc import (DatabaseError, DataError, InterfaceError,
InvalidRequestError)
from werkzeug.utils import secure_filename
from app import db
from distribusikan.distribusisinfo import DistribusisInfo
from forms.distribusiform import DistribusiForm from forms.distribusiform import DistribusiForm
from forms.editorform import EditorForm from forms.editorform import EditorForm
from forms.publicthemeform import PublicThemeForm from forms.publicthemeform import PublicThemeForm
@ -13,10 +17,7 @@ from forms.selectorform import SelectorForm
from forms.themeform import ThemeForm from forms.themeform import ThemeForm
from forms.uploadform import UploadForm from forms.uploadform import UploadForm
from models.distribusimodel import Distribusis from models.distribusimodel import Distribusis
from sqlalchemy.exc import (DatabaseError, DataError, InterfaceError,
InvalidRequestError)
from statuspengguna.helper import UserHelper from statuspengguna.helper import UserHelper
from werkzeug.utils import secure_filename
def Editor(): def Editor():

2
verse/templates/distribusi.html → verse/distribusikan/templates/distribusikan/distribusi.html

@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "base/base.html" %}
{% block main %} {% block main %}
<div id="buttons"> <div id="buttons">
<div class="overview"> <div class="overview">

0
verse/templates/distribusiworkflow/editcss.html → verse/distribusikan/templates/distribusikan/distribusiworkflow/editcss.html

2
verse/templates/distribusiworkflow/launch.html → verse/distribusikan/templates/distribusikan/distribusiworkflow/launch.html

@ -3,7 +3,7 @@
<p class="tooltip">Run distribusi on your files. This will generate your website and make <p class="tooltip">Run distribusi on your files. This will generate your website and make
your content public. <span class="tooltiptext">Distribusi will unpack your zip file and turn it into a website! your content public. <span class="tooltiptext">Distribusi will unpack your zip file and turn it into a website!
</span></p> </span></p>
<form method="POST" enctype="multipart/form-data" action="{{ url_for('distribusi') }}"> <form method="POST" enctype="multipart/form-data" action="{{ url_for('distribusikan.distribusi') }}">
{{ distribusiform.csrf_token }} {{ distribusiform.csrf_token }}
{% if files_uploaded or distribusi_live %} {% if files_uploaded or distribusi_live %}
<fieldset class="button required"> <fieldset class="button required">

2
verse/templates/distribusiworkflow/selector.html → verse/distribusikan/templates/distribusikan/distribusiworkflow/selector.html

@ -1,7 +1,7 @@
<div id="distribusi" class="workflow"> <div id="distribusi" class="workflow">
<h2>Welcome back to your Distribusi</h2> <h2>Welcome back to your Distribusi</h2>
<p>You have already uploaded a distribusi website:</p> <p>You have already uploaded a distribusi website:</p>
<form method="POST" enctype="multipart/form-data" action="{{ url_for('selector') }}"> <form method="POST" enctype="multipart/form-data" action="{{ url_for('distribusikan.selector') }}">
{{ selectorform.csrf_token }} {{ selectorform.csrf_token }}
<fieldset class="required"> <fieldset class="required">
{{ selectorform.distribusis.label }} {{ selectorform.distribusis.label }}

4
verse/templates/distribusiworkflow/theme.html → verse/distribusikan/templates/distribusikan/distribusiworkflow/theme.html

@ -4,7 +4,7 @@
step 3.</p> step 3.</p>
<p>Don't forget to press Save</p> <p>Don't forget to press Save</p>
<hr> <hr>
<form method="POST" enctype="multipart/form-data" action="{{ url_for('theme') }}"> <form method="POST" enctype="multipart/form-data" action="{{ url_for('distribusikan.theme') }}">
{{ themeform.csrf_token }} {{ themeform.csrf_token }}
<fieldset class="required"> <fieldset class="required">
{{ themeform.theme.label }} {{ themeform.theme.label }}
@ -23,7 +23,7 @@
{% endif %} {% endif %}
</form> </form>
<hr> <hr>
<form method="POST" enctype="multipart/form-data" action="{{ url_for('theme') }}"> <form method="POST" enctype="multipart/form-data" action="{{ url_for('distribusikan.theme') }}">
{{ publicthemeform.csrf_token }} {{ publicthemeform.csrf_token }}
<fieldset id="publicthemes" class="required"> <fieldset id="publicthemes" class="required">
{{ publicthemeform.publicthemes.label }} {{ publicthemeform.publicthemes.label }}

2
verse/templates/distribusiworkflow/upload.html → verse/distribusikan/templates/distribusikan/distribusiworkflow/upload.html

@ -1,7 +1,7 @@
<div id="upload" class="workflow"> <div id="upload" class="workflow">
<h2>Step 1: Upload</h2> <h2>Step 1: Upload</h2>
<p>Upload your files here:</p> <p>Upload your files here:</p>
<form method="POST" enctype="multipart/form-data" action="{{ url_for('upload') }}"> <form method="POST" enctype="multipart/form-data" action="{{ url_for('distribusikan.upload') }}">
{{ uploadform.csrf_token }} {{ uploadform.csrf_token }}
<fieldset class="required"> <fieldset class="required">
{{ uploadform.sitename.label }} {{ uploadform.sitename.label }}

2
verse/templates/editor.html → verse/distribusikan/templates/distribusikan/editor.html

@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "base/base.html" %}
{% block main %} {% block main %}
<form method="POST" enctype="multipart/form-data" action="{{ url_for('editor') }}" class="editform"> <form method="POST" enctype="multipart/form-data" action="{{ url_for('editor') }}" class="editform">
<div class="editareas"> <div class="editareas">

3
verse/themeselector.py → verse/distribusikan/themeselector.py

@ -1,8 +1,9 @@
import os import os
import shutil import shutil
from distribusisinfo import DistribusisInfo
from flask import render_template from flask import render_template
from distribusikan.distribusisinfo import DistribusisInfo
from forms.distribusiform import DistribusiForm from forms.distribusiform import DistribusiForm
from forms.publicthemeform import PublicThemeForm from forms.publicthemeform import PublicThemeForm
from forms.selectorform import SelectorForm from forms.selectorform import SelectorForm

9
verse/upload.py → verse/distribusikan/upload.py

@ -1,15 +1,16 @@
import os import os
import shutil import shutil
from app import db
from distribusiselector import SelectCurrentDistribusi
from flask import flash from flask import flash
from flask_login import current_user from flask_login import current_user
from sqlalchemy.exc import (DatabaseError, DataError, IntegrityError,
InterfaceError, InvalidRequestError)
from app import db
from distribusikan.distribusiselector import SelectCurrentDistribusi
from forms.uploadform import UploadForm from forms.uploadform import UploadForm
from models.distribusimodel import Distribusis from models.distribusimodel import Distribusis
from models.usermodel import User from models.usermodel import User
from sqlalchemy.exc import (DatabaseError, DataError, IntegrityError,
InterfaceError, InvalidRequestError)
from statuspengguna.helper import UserHelper from statuspengguna.helper import UserHelper

9
verse/uploadpage.py → verse/distribusikan/uploadpage.py

@ -1,14 +1,15 @@
from app import APP
from distribusiselector import SelectorVisible
from distribusisinfo import DistribusisInfo
from flask import render_template from flask import render_template
from app import APP
from distribusikan.distribusiselector import SelectorVisible
from distribusikan.distribusisinfo import DistribusisInfo
from distribusikan.upload import UploadNewDistribusi, UploadUpdatedFiles
from forms.distribusiform import DistribusiForm from forms.distribusiform import DistribusiForm
from forms.publicthemeform import PublicThemeForm from forms.publicthemeform import PublicThemeForm
from forms.selectorform import SelectorForm from forms.selectorform import SelectorForm
from forms.themeform import ThemeForm from forms.themeform import ThemeForm
# UserPengguna # UserPengguna
from statuspengguna.helper import UserHelper from statuspengguna.helper import UserHelper
from upload import UploadNewDistribusi, UploadUpdatedFiles
def UploadPage(): def UploadPage():

3
verse/forms/uploadform.py

@ -1,4 +1,3 @@
from app import settings
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 (IntegerField, SelectField, StringField, SubmitField, from wtforms import (IntegerField, SelectField, StringField, SubmitField,
@ -6,6 +5,8 @@ from wtforms import (IntegerField, SelectField, StringField, SubmitField,
from wtforms.validators import (DataRequired, Length, NumberRange, from wtforms.validators import (DataRequired, Length, NumberRange,
ValidationError) ValidationError)
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"""

3
verse/models/usermodel.py

@ -1,6 +1,7 @@
from app import db
from flask_login import UserMixin from flask_login import UserMixin
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"""

83
verse/start.py

@ -2,36 +2,33 @@
from datetime import timedelta from datetime import timedelta
# Interface! these are seperate files in main folder
from adminpage import AdminPage
from app import create_app, login_manager
from distribusiselector import DistribusiSelector
# Distribusi Information
from distribusisinfo import DistribusisInfo
from distribusiworkflow import DistribusiWorkflow
from editor import Editor
from flask import (Blueprint, redirect, render_template, send_from_directory, from flask import (Blueprint, redirect, render_template, send_from_directory,
session, url_for) 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_mail import Mail from flask_mail import Mail
from flask_wtf.csrf import CSRFError from flask_wtf.csrf import CSRFError
# Interface! these are seperate files in main folder
from adminpage import AdminPage
from app import create_app, login_manager
from distribusikan.distribusikan import distribusikan
from distribusikan.distribusisinfo import DistribusisInfo
# Use upload form to populate filters # Use upload form to populate filters
from forms.uploadform import UploadForm from forms.uploadform import UploadForm
from models.distribusimodel import Distribusis from models.distribusimodel import Distribusis
from models.usermodel import User from models.usermodel import User
from statuspengguna.forgotpassword import ForgotPassword from statuspengguna.forgotpassword import forgot_password
# UserPengguna
from statuspengguna.helper import UserHelper from statuspengguna.helper import UserHelper
from statuspengguna.loginuser import LoginUser from statuspengguna.loginuser import login_section
from statuspengguna.registeruser import RegisterUser from statuspengguna.registeruser import register_user
from statuspengguna.resetpassword import ResetPassword
from themeselector import ThemeSelector
from uploadpage import UploadPage
APP = create_app() APP = create_app()
stash_page = Blueprint("stash_page", __name__, static_folder="stash") stash_page = Blueprint("stash_page", __name__, static_folder="stash")
APP.register_blueprint(login_section, url_prefix="/login")
APP.register_blueprint(register_user, url_prefix="/register")
APP.register_blueprint(forgot_password, url_prefix="/login/forgotpassword")
APP.register_blueprint(distribusikan)
APP.register_blueprint(stash_page) APP.register_blueprint(stash_page)
mail = Mail(APP)
@APP.before_request @APP.before_request
@ -60,7 +57,7 @@ def index():
categories = uploadform.category.choices categories = uploadform.category.choices
adminuser = isadminuser() adminuser = isadminuser()
template = render_template( template = render_template(
"index.html", "base/index.html",
distribusisindex=distribusisindex, distribusisindex=distribusisindex,
years=years, years=years,
categories=categories, categories=categories,
@ -71,25 +68,7 @@ def index():
@APP.route("/help") @APP.route("/help")
def help(): def help():
return render_template("help.html") return render_template("base/help.html")
@APP.route("/distribusi", methods=["GET", "POST"])
@login_required
def distribusi():
return DistribusiWorkflow()
@APP.route("/upload", methods=["POST"])
@login_required
def upload():
return UploadPage()
@APP.route("/theme", methods=["GET", "POST"])
@login_required
def theme():
return ThemeSelector()
@APP.route("/publicthemes/<path>") @APP.route("/publicthemes/<path>")
@ -100,18 +79,6 @@ def publicthemes(path):
return send_from_directory("themes", cssfile, as_attachment=True) return send_from_directory("themes", cssfile, as_attachment=True)
@APP.route("/editor", methods=["GET", "POST"])
@login_required
def editor():
return Editor()
@APP.route("/selector", methods=["GET", "POST"])
@login_required
def selector():
return DistribusiSelector()
@APP.route("/stash") @APP.route("/stash")
def shortstashurl(): def shortstashurl():
return redirect(url_for("index")) return redirect(url_for("index"))
@ -132,26 +99,6 @@ def logout():
return redirect(url_for("index")) return redirect(url_for("index"))
@APP.route("/login", methods=["GET", "POST"])
def login():
return LoginUser()
@APP.route("/register", methods=["GET", "POST"])
def register():
return RegisterUser()
@APP.route("/forgotpassword", methods=["GET", "POST"])
def forgotpassword():
return ForgotPassword(mail)
@APP.route("/resetpassword/<path>", methods=["GET", "POST"])
def resetpassword(path):
return ResetPassword(path)
@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

0
verse/statuspengguna/__init__.py

24
verse/statuspengguna/forgotpassword.py

@ -1,14 +1,28 @@
from datetime import datetime from datetime import datetime
from uuid import uuid1 from uuid import uuid1
from app import db from flask import Blueprint, render_template
from flask import render_template from flask_mail import Mail, Message
from flask_mail import Message
from forms.forgotpasswordform import ForgotPasswordForm
from models.usermodel import User
from sqlalchemy.exc import (DatabaseError, DataError, InterfaceError, from sqlalchemy.exc import (DatabaseError, DataError, InterfaceError,
InvalidRequestError) InvalidRequestError)
from app import db, get_app
from forms.forgotpasswordform import ForgotPasswordForm
from models.usermodel import User
mail = Mail(get_app())
forgot_password = Blueprint(
"forgotpassword",
__name__,
template_folder="templates/statuspengguna",
static_folder="static",
)
@forgot_password.route("/", methods=["GET", "POST"])
def forgotpassword():
return ForgotPassword(mail)
def ForgotPassword(mail): def ForgotPassword(mail):
forgotpasswordform = ForgotPasswordForm() forgotpasswordform = ForgotPasswordForm()

9
verse/statuspengguna/helper.py

@ -1,14 +1,15 @@
import os import os
from app import db
from distribusisinfo import DistribusisInfo
from flask import flash from flask import flash
from flask_login import current_user from flask_login import current_user
from models.distribusimodel import Distribusis
from models.usermodel import User
from sqlalchemy.exc import (DatabaseError, DataError, InterfaceError, from sqlalchemy.exc import (DatabaseError, DataError, InterfaceError,
InvalidRequestError) InvalidRequestError)
from app import db
from distribusikan.distribusisinfo import DistribusisInfo
from models.distribusimodel import Distribusis
from models.usermodel import User
class UserHelper: class UserHelper:
def is_zip_uploaded(distribusiname): def is_zip_uploaded(distribusiname):

19
verse/statuspengguna/loginuser.py

@ -1,9 +1,23 @@
from flask import abort, flash, redirect, render_template, request, url_for from flask import (Blueprint, abort, flash, redirect, render_template, request,
send_from_directory, session, 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
from forms.loginform import LoginForm from forms.loginform import LoginForm
from models.usermodel import User from models.usermodel import User
login_section = Blueprint(
"login",
__name__,
template_folder="templates/statuspengguna",
static_folder="static",
)
@login_section.route("/", methods=["GET", "POST"])
def login():
return LoginUser()
def LoginUser(): def LoginUser():
loginform = LoginForm() loginform = LoginForm()
@ -14,11 +28,14 @@ def LoginUser():
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):
print(type(user))
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)
return abort(400) return abort(400)
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")

21
verse/statuspengguna/registeruser.py

@ -1,13 +1,26 @@
from app import db from flask import Blueprint, flash, redirect, render_template, url_for
from flask import 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 forms.registerform import RegisterForm
from models.usermodel import User
from sqlalchemy.exc import (DatabaseError, DataError, IntegrityError, from sqlalchemy.exc import (DatabaseError, DataError, IntegrityError,
InterfaceError, InvalidRequestError) InterfaceError, InvalidRequestError)
from werkzeug.routing import BuildError from werkzeug.routing import BuildError
from app import db
from forms.registerform import RegisterForm
from models.usermodel import User
register_user = Blueprint(
"register",
__name__,
template_folder="templates/statuspengguna",
static_folder="static",
)
@register_user.route("/", methods=["GET", "POST"])
def register():
return RegisterUser()
def RegisterUser(): def RegisterUser():
registerform = RegisterForm() registerform = RegisterForm()

20
verse/statuspengguna/resetpassword.py

@ -1,15 +1,29 @@
from datetime import datetime from datetime import datetime
from app import db
from flask import flash, redirect, render_template, url_for from flask import 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 forms.resetpasswordform import ResetPasswordForm
from models.usermodel import User
from sqlalchemy.exc import (DatabaseError, DataError, IntegrityError, from sqlalchemy.exc import (DatabaseError, DataError, IntegrityError,
InterfaceError, InvalidRequestError) InterfaceError, InvalidRequestError)
from werkzeug.routing import BuildError from werkzeug.routing import BuildError
from app import db
from forms.resetpasswordform import ResetPasswordForm
from models.usermodel import User
from statuspengguna import statuspengguna
reset_password = Blueprint(
"reset_password",
__name__,
template_folder="templates/statuspengguna",
static_folder="static",
)
@reset_password.route("/resetpassword/<path>", methods=["GET", "POST"])
def resetpassword(path):
return ResetPassword(path)
def ResetPassword(path): def ResetPassword(path):
linkvalid = False linkvalid = False

69
verse/statuspengguna/static/css/dropdown.css

@ -0,0 +1,69 @@
/* Dropdown Button */
/* for sorting on year and category
*/
button {
background-color: #E0B0FF;
text-decoration: none;
border: none;
}
.filter {
display: none;
}
.activebtn {
background-color: #62b264;
}
.show {
display: block;
}
.dropdown {
position: relative;
display: inline-block;
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
position: absolute;
background-color: #E0B0FF;
min-width: 120px;
border: 2px solid;
z-index: 1;
border-style: outset;
}
/* Links inside the dropdown */
.dropdown-content button {
color: black;
padding: 6px;
border: none;
min-width: inherit;
text-align: left;
text-decoration: none;
display: block;
}
.dropbtn {
margin-top: 1em;
}
/* Change color of dropdown links on hover */
.dropdown-content button:hover {background-color: #62b264;}
/* Show the dropdown menu on hover */
.dropdown:hover .dropdown-content {display: block;}
/* Change the background color of the dropdown button when the dropdown content is shown */
.dropdown:hover .dropbtn {background-color: #62b264;}
@media only screen and (min-device-width: 320px) and (max-device-width: 480px) {
.dropdown-content button {
font-size: 0.7em;
}
.container > button {
font-size: 0.7em;
}
.dropdown > button {
font-size: 0.7em;
}
}

50
verse/statuspengguna/static/css/editor.css

@ -0,0 +1,50 @@
.editareas {
margin: auto;
display: flex;
justify-content: flex-start;
}
.editarea {
width: 30%;
border: 3px solid #E0B0FF;
border-style: outset;
margin-right: 1em;
margin-left: 0;
}
.editor {
min-width: 35%;
}
.editform {
width: 100%%;
margin: 0 auto;
}
#editorsubmitform {
padding-top: 1em;
}
.required label {
display: block;
padding-bottom: 2px;
width: 100%
}
textarea {
width: 100%;
height: 100%;
box-sizing: border-box;
min-height: 250px;
background: #E0B0FF;
outline: none;
font-family: Courier, sans-serif;
font-size: 16px;
}
iframe {
bottom: 0;
position: relative;
margin-top: 1em;
width: 100%;
height: 30em;
}
#html {
background-color: #60337F;
color: lightgrey;
}

53
verse/statuspengguna/static/css/selector.css

@ -0,0 +1,53 @@
.selector-style {
padding: 0;
width: 20em;
max-width: 20em;
position: relative;
border: none;
background: #E0B0FF;
text-decoration: none;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
margin: 1px;
}
.selector-style select {
padding: 0.2em 0.2em;
width: 20em;
max-width: 20em;
border: none;
box-shadow: none;
background-color: #E0B0FF;
background-image: none;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}
.selector-style:after {
top: 50%;
left: 95%;
border: solid;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
border-color: rgba(0, 0, 0, 0);
border-top-color: #000000;
margin-top: -2px;
z-index: 100;
}
select.selector option{
color: white;
background-color: #60337F;
padding: 0 10px;
}
.selector-style select:focus {
outline: none;
}
.selector-style select option:hover {
background: #60337F;
}

286
verse/statuspengguna/static/css/style.css

@ -0,0 +1,286 @@
body
{
font-family: monospace, monospace;
font-size: 15px;
background-color: #fdfdfd;
color:#29d148;
word-wrap: break-word;
line-height: 1.1;
}
div#login{
width: 30%;
margin-left: auto;
margin-right: auto;
background-color:#fdfdfd;
text-decoration: none;
}
div#login form {
width: 24em;
margin: 0 auto;
padding-left: 15%;
padding-right: 15%;
}
input[type=text], input[type=password], input[type=file] {
color: #C397DF;
width: 18em;
max-width: 18em;
background-color: #fdfdfd;
border: 1px solid #E0B0FF;
}
div#upload form {
padding-right: 15%;
}
.workflow{
margin-top: 1em;
padding: 0.5em;
padding-left: auto;
padding-right: auto;
width: 31em;
background-color:#fdfdfd;
text-decoration: none;
scroll-behavior: smooth;
border-style: outset;
}
.workflow > p {
padding-left: 1em;
}
.workflow > h2 {
padding-left: 0.4em;;
}
.workflow input{
max-width: 20em;
}
#mainworkflow
{
width: 30em;
margin:0 auto;
}
#distribusiverse {
margin-bottom: 11em;
}
#distribusi-index {
padding-left: 1em;
}
div#buttons{
position: fixed;
top: 0.5em;
right: 0.5em;
display:flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
div#buttons .distribusi input{
border: none;
background: #fff600;
text-decoration: none;
margin: 0.2em;
}
div#buttons .distribusi input:hover{
background: #ffbf00;
}
fieldset.required {
border: none;
}
fieldset.required > ul {
padding-left: 0px;
}
fieldset.required > ul > li{
list-style-type: none;
}
fieldset.tagfield > input {
width: 100%;
max-width: 100%;
}
#publicthemes > ul {
max-height: 20em;
overflow: auto;
}
#publicthemes > ul > li{
word-break: break-all;
}
input {
border: none;
background: #E0B0FF;
text-decoration: none;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
margin: 0.2em;
}
input:hover {
background: #60337F;
}
input[type="submit"]:disabled:hover,
input[type="submit"]:disabled,
input[type="submit"]:disabled:focus {
background-color: #2D3039;
color: #d28cff;
}
.error {
font-size: 110%;
color: #F92020;
}
#delete {
color: black;
background-color: #F92020;
}
#update {
color: black;
background-color: #62b264;
}
#tutors {
color: black;
background-color: #62b264;
}
/* unvisited link */
a:link {
color: #fff600;
}
/* visited link */
a:visited {
color: #d28cff;
}
/* mouse over link */
a:hover {
color: #60337F;
}
/* selected link */
a:active {
color: white;
}
/* STOLEN GOODS */
#fancyboi::before {
content: "$ ";
}
@media (prefers-reduced-motion: no-preference) {
@keyframes flash {
50% { opacity: 0; }
}
@keyframes reveal {
from { width: 2em; } /* Width of ::before */
to { width: 55%; }
}
#fancyboi {
width: 55%;
padding: 0.5em;
overflow: hidden;
white-space: nowrap;
animation: reveal 4s linear;
text-overflow: "█";
background-color: #2D3039;
}
#fancyboi::after {
content: "█";
animation: flash 0.5s step-end infinite;
}
}
div.maincontent{
width: 55%;
border: 3px #E0B0FF;
margin-top: 0.5em;
padding: 0.5em;
border-style: outset;
}
.tags{
background-color: #000;
color: #fff;
display: inline-block;
padding-left: 4px;
padding-right: 4px;
text-align: center;
margin: 1px;
}
.searched {
background: #fff600 !important;
color: black !important;
}
.tooltip {
position: relative;
display: inline-block;
border-bottom: 1px dotted black;
}
.tooltip .tooltiptext {
visibility: hidden;
width: 120px;
background-color: black;
color: #fff;
text-align: center;
padding: 5px 0;
position: absolute;
z-index: 1;
bottom: 100%;
left: 50%;
margin-left: -60px;
/* Fade in tooltip - takes 1 second to go from 0% to 100% opac: */
opacity: 0;
transition: opacity 2s;
}
.tooltip:hover .tooltiptext {
visibility: visible;
opacity: 1;
}
.code-example {
width: 100%;
color: black;
padding: 1em;
box-sizing: border-box;
background: #E0B0FF;
outline: none;
font-family: Courier, sans-serif;
font-size: 16px;
}
/*
Project colors so far.
light
#E0B0FF
medium
#d28cff
dark
#60337F
background dark
#2D3039
yellow important
#fff600
red: danger
ff5a5a
backgrounds
*/

6
verse/statuspengguna/static/icons/about.txt

@ -0,0 +1,6 @@
This favicon was generated using the following font:
- Font Title: Klee One
- Font Author: Copyright 2020 The Klee Project Authors (https://github.com/fontworks-fonts/Klee)
- Font Source: http://fonts.gstatic.com/s/kleeone/v5/LDIxapCLNRc6A8oT4q4AOeekWPrP.ttf
- Font License: SIL Open Font License, 1.1 (http://scripts.sil.org/OFL))

BIN
verse/statuspengguna/static/icons/android-chrome-192x192.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

BIN
verse/statuspengguna/static/icons/android-chrome-512x512.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
verse/statuspengguna/static/icons/apple-touch-icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
verse/statuspengguna/static/icons/favicon-16x16.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 B

BIN
verse/statuspengguna/static/icons/favicon-32x32.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 B

BIN
verse/statuspengguna/static/icons/favicon.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

1
verse/statuspengguna/static/icons/site.webmanifest

@ -0,0 +1 @@
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}

92
verse/statuspengguna/static/js/dropdown.js

@ -0,0 +1,92 @@
filterSelection("all", "None");
function filterSelection(c, name, id) {
resetDropDownButtons();
var i;
var button = document.getElementById(id);
if(button){
button.innerText = name;
addClass(button, "activebtn");
}
var alldistribusis = document.getElementsByClassName("filter");
if (c == "all") {
for (i = 0; i < alldistribusis.length; i++) {
addClass(alldistribusis[i], "show");
}
}
else {
for (i = 0; i < alldistribusis.length; i++) {
removeClass(alldistribusis[i], "show");
if (alldistribusis[i].className.indexOf(c) > -1) {
addClass(alldistribusis[i], "show");
}
}
}
}
function resetDropDownButtons(){
document.getElementById("Year").innerText = "Year";
document.getElementById("Category").innerText = "Category";
allactivebuttons = document.getElementsByClassName("activebtn");
for(var i = 0;allactivebuttons.length; i++) {
removeClass(allactivebuttons[i], "activebtn");
}
}
function addClass(element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
arr2 = name.split(" ");
for (i = 0; i < arr2.length; i++) {
if (arr1.indexOf(arr2[i]) == -1) {element.className += " " + arr2[i];}
}
}
function removeClass(element, name) {
var i, arr1, arr2;
arr1 = element.className.split(" ");
arr2 = name.split(" ");
for (i = 0; i < arr2.length; i++) {
while (arr1.indexOf(arr2[i]) > -1) {
arr1.splice(arr1.indexOf(arr2[i]), 1);
}
}
element.className = arr1.join(" ");
}
let searchInput = document.getElementById('tagsearch');
let timeout = null;
// Listen for keystroke events
searchInput.addEventListener('keyup', function (e) {
// Clear the timeout if it has already been set.
clearTimeout(timeout);
// Make a new timeout set to go off in 1000ms (1 second)
timeout = setTimeout(function () {
console.log('Input Value:', searchInput.value);
if (searchInput.value.length > 2) {
searchTags(searchInput.value);
} else {
clearSearchTags();
}
}, 1000);
});
function searchTags(searchInput) {
let tag_ele = document.getElementsByClassName('tags');
for (var i = 0; i < tag_ele.length; ++i) {
let searchText = searchInput.toLowerCase().trim();
let tagtext = tag_ele[i].innerText.toLowerCase();
if(searchText.includes(tagtext) || tagtext.includes(searchText)) {
addClass(tag_ele[i], "searched");
}
else {
removeClass(tag_ele[i], "searched");
}
}
}
function clearSearchTags() {
let tag_ele = document.getElementsByClassName('tags');
for (var i = 0; i < tag_ele.length; ++i) {
removeClass(tag_ele[i], "searched");
}
}

19
verse/statuspengguna/static/js/editorupdate.js

@ -0,0 +1,19 @@
function update() {
var html = document.getElementById("html");
var css = document.getElementById("css");
var code = document.getElementById("code").contentWindow.document;
document.body.onkeyup = function(){
code.open();
code.writeln(html.value+"<style>"+css.value+"</style>");
code.close();
};
document.addEventListener("DOMContentLoaded", function(){
code.open();
code.writeln(html.value+"<style>"+css.value+"</style>");
code.close();
});
};
update();

25
verse/statuspengguna/static/js/script.js

@ -0,0 +1,25 @@
console.log("everything is still smooth")
function scrollToTheme() {
var uploadsuccessful = document.getElementById("uploadsuccessful");
if(uploadsuccessful){
const theme = document.getElementById('theme')
theme.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
}
function scrollToLaunch() {
var cssSelected = document.getElementById("cssSelected");
if(cssSelected){
const launch = document.getElementById('launch')
launch.scrollIntoView({ behavior: 'smooth', block: 'end' });
}
}
document.addEventListener("DOMContentLoaded", scrollToTheme);
document.addEventListener("DOMContentLoaded", scrollToLaunch);
// function(e) {
// (e.keyCode === 13 || e.keyCode === 32) && $(this).trigger("click")
// }

75
verse/statuspengguna/static/svg/arrow_1.svg

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="240"
height="320"
viewBox="0 0 63.5 84.666667"
version="1.1"
id="svgArrowOne"
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
sodipodi:docname="arrow_1.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="px"
showgrid="false"
units="px"
inkscape:zoom="1"
inkscape:cx="236"
inkscape:cy="70"
inkscape:window-width="1916"
inkscape:window-height="1041"
inkscape:window-x="1366"
inkscape:window-y="18"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<circle
id="path865"
style="fill:#060000;stroke:#fcfffe;stroke-width:0.264583"
cx="167.50412"
cy="23.866825"
r="0.211455" />
<circle
id="path867"
style="fill:#e0b0ff;stroke:#fcfffe;stroke-width:0.264583;fill-opacity:1"
cx="167.50412"
cy="23.866825"
r="0.211455" />
<circle
id="path2716"
style="fill:#d28cff;stroke:#fcfffe;stroke-width:0.264583"
cx="31.623327"
cy="-54.739456"
r="0.1057275" />
<circle
id="path2718"
style="fill:#d28cff;stroke:#fcfffe;stroke-width:0.264583"
cx="31.623327"
cy="-54.739456"
r="0.1057275" />
<path
style="fill:#d28cff;fill-opacity:1;stroke:none;stroke-width:0.799999"
id="path2732"
d="m 19.948434,3.1817159 c 1.290131,0.6550689 2.512225,1.4411814 3.755485,2.1807733 1.793529,1.0335667 3.565214,2.1021852 5.308482,3.2186226 0.483624,0.3097273 0.976024,0.6070071 1.443413,0.9407313 0.457224,0.3264641 0.885243,0.6920049 1.327862,1.0380079 2.123546,1.795334 3.693565,4.041838 4.640125,6.658655 0.242448,0.67026 0.417224,1.3631 0.625834,2.04465 0.468096,1.928539 0.850726,3.889399 1.025174,5.869019 0.146409,1.661472 0.09044,3.337613 0.06891,5.002416 -0.136327,2.53704 -0.886677,4.958631 -1.507659,7.401952 -0.562415,2.08257 -2.195008,3.525988 -3.642546,5.02172 -1.668862,1.796187 -3.430227,3.511629 -4.96204,5.428684 -1.232474,1.501685 -2.187443,3.200289 -3.147382,4.881737 -1.04435,1.719871 -1.86704,3.57665 -2.548164,5.467477 -0.710967,2.173634 -0.907385,4.460639 -1.024063,6.730664 0.02091,1.346742 0.05687,2.707192 0.493364,3.995719 0.26353,0.777933 0.396191,0.938664 0.795115,1.653278 0.654367,1.054661 1.365786,2.066507 2.102377,3.064017 0,0 3.841737,-0.248322 3.841737,-0.248322 v 0 c -0.75511,-0.983935 -1.542788,-1.939549 -2.17802,-3.011543 -0.382704,-0.652497 -0.537692,-0.849823 -0.799641,-1.562883 -0.455204,-1.239128 -0.493109,-2.567154 -0.52219,-3.871724 0.107265,-2.234121 0.278343,-4.485997 1.012129,-6.617327 0.708365,-1.865136 1.556754,-3.687384 2.575162,-5.404406 0.953056,-1.662009 1.928715,-3.32604 3.127534,-4.825259 1.51579,-1.902804 3.233504,-3.631578 4.905512,-5.395754 1.510255,-1.536197 3.212571,-3.04624 3.747334,-5.218498 0.540033,-2.47709 1.199993,-4.93743 1.330515,-7.483557 0.02558,-1.263529 0.06192,-2.073423 0.0096,-3.332359 C 41.644752,24.222411 41.147902,21.675409 40.546318,19.16389 40.076453,17.470971 39.976922,16.848842 39.271149,15.277213 38.380408,13.293695 37.001362,11.650365 35.365848,10.236089 34.920391,9.8793346 34.491789,9.5004423 34.02947,9.1658256 33.563896,8.8288536 33.065526,8.5396762 32.585453,8.223701 30.879732,7.1010218 29.144655,6.0327407 27.391958,4.9847267 26.212505,4.238663 25.04853,3.4635151 23.848505,2.7523961 c 0,0 -3.900058,0.4293198 -3.900058,0.4293198 z" />
<path
style="fill:#d28cff;fill-opacity:1;stroke:none;stroke-width:0.799999"
id="path2736"
d="m 17.143337,69.050471 c 1.633713,0.894598 3.185906,1.900385 4.678149,3.014075 1.115423,0.934426 2.160169,1.94547 3.113059,3.044203 1.826876,2.397014 -1.146831,1.665475 4.779041,1.263248 0.383141,-1.686153 0.758291,-3.374861 1.165924,-5.055598 0.206131,-0.876517 0.390895,-1.75066 0.653066,-2.611993 0,0 -3.799028,-0.103103 -3.799028,-0.103103 v 0 c -0.220279,0.87104 -0.384717,1.750875 -0.582906,2.627255 -0.396558,1.670132 -0.773763,3.348908 -1.349638,4.968864 1.273906,0.05246 2.548034,0.09977 3.821714,0.157393 0.02885,0.0013 -0.07003,0.03579 -0.08584,0.01161 -0.06107,-0.09337 -0.07566,-0.209923 -0.112684,-0.315174 -0.133537,-0.379648 -0.146335,-0.493044 -0.361696,-0.837912 -0.08452,-0.135356 -0.188793,-0.257328 -0.283188,-0.385993 -1.017286,-1.099923 -2.077482,-2.15043 -3.232635,-3.10924 -1.452916,-1.095015 -2.937697,-2.134709 -4.528692,-3.02179 0,0 -3.87465,0.354142 -3.87465,0.354142 z" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.9 KiB

12
verse/statuspengguna/static/svg/arrow_2.svg

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="240" height="320" version="1.1" viewBox="0 0 63.5 84.667" xmlns="http://www.w3.org/2000/svg">
<circle cx="167.5" cy="23.867" r=".21146" fill="#060000" stroke="#fcfffe" stroke-width=".26458"/>
<circle cx="167.5" cy="23.867" r=".21146" fill="#e0b0ff" stroke="#fcfffe" stroke-width=".26458"/>
<g fill="#d28cff">
<circle cx="31.623" cy="-54.739" r=".10573" stroke="#fcfffe" stroke-width=".26458"/>
<circle cx="31.623" cy="-54.739" r=".10573" stroke="#fcfffe" stroke-width=".26458"/>
<path d="m29.598 1.3629c0.29231 0.93057 0.37445 1.9094 0.44145 2.8774 0.01955 0.99076 0.29893 1.9483 0.43855 2.9253 0.04901 1.1628 0.31687 2.2714 0.7734 3.3386 0.60807 1.244 1.6241 2.1846 2.6231 3.1104 0.76132 0.7147 1.5224 1.4053 2.414 1.9528 0.85013 0.49091 1.8227 0.71794 2.7627 0.97569 1.4036 0.22312 2.1015 0.68412 3.1203 1.648 1.1101 1.0733 1.7779 2.4463 2.4311 3.8184 0.5827 1.142 0.76303 2.3828 0.73638 3.6503-0.08765 1.5129-0.67764 2.6923-1.5432 3.8976-0.84272 1.225-2.1589 1.8621-3.4214 2.5577-1.3039 0.74177-2.5458 1.586-3.8965 2.2408-1.5184 0.78493-3.077 1.4779-4.6378 2.1709-1.2968 0.70155-2.6371 1.3714-3.7845 2.3055-1.5755 1.3431-2.9301 2.8922-4.2407 4.4866-1.0773 1.3646-2.2517 2.7443-2.9262 4.3683-0.12219 0.2942-0.20988 0.60157-0.31482 0.90236-0.3176 1.1367-0.50828 2.2967-0.36852 3.4764 0.04693 0.39614 0.19687 1.057 0.27962 1.4461 0.30758 1.2289 0.84547 2.3725 1.4798 3.4625 0.70009 1.3121 1.6509 2.4545 2.6734 3.5243 1.0661 1.0736 2.1636 2.1225 3.154 3.2675 0.78168 0.87789 1.0179 1.9433 1.1372 3.0756 0.03544 0.92388 0.11577 1.8587 0.07073 2.7841-0.01773 0.36408-0.1093 0.87867-0.16701 1.2409-0.09034 1.015-0.40258 1.9744-0.65202 2.9542-0.22907 0.93923-0.24592 1.9133-0.26994 2.875 0.01627 0.16165 0.03253 0.3233 0.04879 0.48495 0 0 3.8677-0.04599 3.8677-0.04599l-0.06033-0.42856c0.0271-0.93446 0.05799-1.8763 0.28398-2.7884 0.25461-0.98959 0.52171-1.9723 0.61567-2.9949 0.18691-1.3678 0.16751-2.7404 0.09837-4.1178-0.10464-1.2084-0.33697-2.37-1.1681-3.3092-0.98696-1.161-2.0984-2.2119-3.1752-3.2885-1.0093-1.0344-1.9609-2.1448-2.6312-3.4346-0.61359-1.0586-1.166-2.1573-1.4984-3.3403-0.02657-0.1263-0.26629-1.2542-0.28656-1.3963-0.16054-1.1256 0.0079-2.2354 0.32978-3.3186 0.10325-0.28669 0.1907-0.57958 0.30976-0.86007 0.67556-1.5915 1.8191-2.9377 2.8755-4.2834 1.3254-1.6128 2.6979-3.0863 4.332-4.3948 1.1702-0.86077 2.4531-1.5682 3.751-2.2163 1.5673-0.6912 3.1104-1.4304 4.6479-2.1857 1.3437-0.6747 2.5823-1.5317 3.8988-2.2576 1.3084-0.71914 2.6043-1.447 3.4487-2.7293 0.89598-1.305 1.4437-2.5132 1.5458-4.1199 0.04656-1.326-0.09489-2.646-0.72638-3.8363-0.70909-1.3836-1.3422-2.8175-2.4524-3.9439-0.95909-0.99062-1.6743-1.6678-3.0935-1.8533-0.92413-0.22693-1.8609-0.47835-2.7296-0.86415-0.37733-0.23195-0.7701-0.43303-1.1225-0.70362-0.56026-0.43018-0.30161-0.27292-0.85155-0.76539-0.15495-0.13876-0.31951-0.26638-0.47927-0.39957-0.94654-0.91944-2.0219-1.7437-2.6195-2.9576-0.46026-1.0278-0.6805-2.1099-0.72907-3.2345-0.13163-0.97099-0.41801-1.9171-0.4545-2.8972-0.062288-0.99479-0.16352-1.9871-0.37122-2.9636l-3.9178 0.11147z"/>
<path d="m22.025 71.064c1.1076 0.81571 1.8963 1.9751 2.6453 3.1096 0.63322 0.93788 1.2476 1.8855 1.6118 2.9617 0.28693 0.82149 0.62284 1.6252 1.0669 2.3743 1.0301 1.4304 1.5291 0.58576 4.4538 0.16545 0.14811-0.02127 0.42422-1.2095 0.46069-1.36 0.25411-0.96357 0.61812-1.6049 1.3587-2.2583 0.75053-0.69358 1.7635-0.9666 2.6863-1.3526 1.0408-0.39579 2.1353-0.68763 3.1287-1.1962 0.12805-0.06035 0.2561-0.12069 0.38414-0.18103 0 0-3.8517-0.43584-3.8517-0.43584-0.12618 0.06059-0.25236 0.12119-0.37854 0.18179-1.0095 0.4429-2.0552 0.79223-3.0867 1.1786-0.97696 0.38612-1.9942 0.73078-2.7537 1.4922-0.6784 0.69992-1.1041 1.5244-1.3418 2.4736-0.08563 0.30808-0.14275 0.60119-0.30832 0.87972-0.05051 0.08497-0.29376 0.21564-0.1952 0.22324 1.2279 0.09468 2.4644-0.01566 3.6945 0.04656 0.07116 0.0036-0.09855 0.1467-0.16824 0.13185-0.0954-0.02032-0.13522-0.1406-0.20282-0.2109-0.48406-0.68952-0.78002-1.4975-1.0935-2.2751-0.36094-1.1214-0.97173-2.1151-1.6698-3.0606-0.6571-0.99538-1.3971-2.1349-2.2397-2.9817-0.09081-0.09127-0.19994-0.16228-0.29991-0.24342l-3.9009 0.33725z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

12
verse/statuspengguna/static/svg/arrow_3.svg

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg width="240" height="320" version="1.1" viewBox="0 0 63.5 84.667" xmlns="http://www.w3.org/2000/svg">
<circle cx="167.5" cy="23.867" r=".21146" fill="#060000" stroke="#fcfffe" stroke-width=".26458"/>
<circle cx="167.5" cy="23.867" r=".21146" fill="#e0b0ff" stroke="#fcfffe" stroke-width=".26458"/>
<g fill="#d28cff">
<circle cx="31.623" cy="-54.739" r=".10573" stroke="#fcfffe" stroke-width=".26458"/>
<circle cx="31.623" cy="-54.739" r=".10573" stroke="#fcfffe" stroke-width=".26458"/>
<path d="m56.965 3.4219c0.12058 1.1521-0.2318 2.054-0.81004 3.0337-1.0875 1.5907-2.5336 2.8659-4.0843 3.9867-2.1505 1.3863-4.4585 2.4853-6.8625 3.3491-2.7815 0.78715-5.6335 1.3087-8.4879 1.7525-3.134 0.44066-6.2863 0.71397-9.4313 1.0632-3.4224 0.40837-6.8733 1.0287-10.07 2.3675-0.54185 0.22694-1.0603 0.5062-1.5904 0.75929-0.89954 0.54647-1.6469 0.92677-2.4068 1.6606-1.3388 1.2929-2.0863 2.9786-2.778 4.6654-0.87449 2.3542-1.198 4.6214-1.1672 7.1174 0.18717 1.5284 0.31332 3.0753 0.6288 4.5852 0.091869 0.43967 0.3934 1.5785 0.51155 2.0327 0.39771 1.1363 0.63254 2.4445 1.5286 3.3253 0.14764 0.14511 0.3231 0.25888 0.48465 0.38832 0.20368 0.10006 0.39798 0.22205 0.61104 0.30019 0.42615 0.15629 1.2969 0.32297 1.7205 0.41193 1.1822 0.24832 2.3631 0.46842 3.5556 0.66151 1.9566 0.35044 3.9445 0.66205 5.8228 1.331 1.3844 0.50374 2.5213 1.4098 3.6121 2.3711 1.0386 0.99728 2.1001 1.9882 2.7426 3.3026 0.16634 0.3403 0.28751 0.70088 0.43126 1.0513 0.86215 2.4558 1.0225 5.0522 0.9327 7.631-0.07031 1.5349-0.29391 3.1185-1.156 4.4316-0.12638 0.19249-0.28466 0.36202-0.42699 0.54304-0.81011 0.9275-1.7382 1.735-2.5931 2.6178-0.73658 0.82062-1.6053 0.85394-2.5586 1.1927-0.94832 0.22808-1.8262 0.65178-2.7421 0.97327-1.1741 0.61913-2.4826 0.76669-3.7501 1.0714-1.2105 0.21338-2.3976 0.48893-3.5183 1.0015-0.67364 0.34917-1.2076 0.81882-1.6407 1.4361l3.8658 0.2497c0.43909-0.54046 0.98065-0.94428 1.6142-1.2389 1.1138-0.46371 2.2851-0.70648 3.4664-0.93518 1.2893-0.27722 2.5716-0.54674 3.7736-1.1162 0.91684-0.34231 1.829-0.69308 2.7728-0.9567 1.0196-0.30093 1.8099-0.54985 2.5486-1.3801 0.87014-0.87766 1.7909-1.7075 2.5674-2.6739 0.13769-0.20005 0.28985-0.39088 0.41308-0.60015 0.82211-1.3961 1.0263-3.0131 1.0537-4.6056 0.05629-2.6169-0.0783-5.2743-0.90909-7.7781-0.13345-0.36853-0.2428-0.74671-0.40035-1.1056-0.60136-1.3698-1.6464-2.4153-2.7131-3.4287-1.0905-1.0008-2.2045-1.983-3.6142-2.5099-0.24452-0.10125-0.48125-0.22386-0.73356-0.30376-0.26822-0.08493-0.54885-0.12408-0.82261-0.18901-1.4524-0.34445-2.9022-0.68462-4.3809-0.90277-1.1723-0.18185-2.3227-0.40058-3.4815-0.65277-0.54954-0.11959-1.1101-0.19272-1.6518-0.34365-0.20174-0.05621-0.39234-0.14664-0.58852-0.21996-0.15779-0.10023-0.32954-0.18128-0.47337-0.30068-0.94359-0.78332-1.2089-2.059-1.6142-3.1487-0.16754-0.59766-0.40066-1.3998-0.53448-2.0013-0.33082-1.487-0.45328-3.013-0.62991-4.523-0.03942-2.3761 0.26799-4.7319 1.1144-6.9675 0.36685-0.8728 0.62759-1.5813 1.1166-2.3961 0.98125-1.6348 2.2842-2.7836 3.9639-3.6713 0.51139-0.24392 1.0106-0.5151 1.5342-0.73175 3.1926-1.3212 6.6474-1.892 10.059-2.2825 3.192-0.33755 6.3934-0.58867 9.5696-1.062 2.856-0.4763 5.7214-0.9862 8.4967-1.8227 2.4241-0.91126 4.7643-2.0293 6.9388-3.445 1.5814-1.1701 3.0403-2.506 4.1596-4.1381 0.60624-1.0679 0.95747-1.9925 0.94037-3.2331h-3.9289z"/>
<path d="m12.023 67.543c0.49829 0.89935 0.97249 1.783 1.2618 2.7744 0.05193 0.50463 0.27477 0.97017 0.38441 1.4597 0.09562 0.42695 0.06722 0.87236 0.05564 1.3052-0.02684 0.65007-0.04547 1.3125-0.23635 1.9412-0.02066 0.06805-0.31569 0.75033-0.34246 0.81269-1.0192 2.7097-0.33194 1.7204 3.7574 1.4613 0.62653-0.65486 1.2245-1.3292 1.8921-1.9454 0.77212-0.76506 1.7378-1.0867 2.7527-1.378 1.0883-0.39202 2.2359-0.50662 3.3814-0.5819 0.64057-0.03615 1.2822-0.04273 1.9235-0.05158 0 0-3.7766-0.59155-3.7766-0.59155-0.64632 0.01315-1.2932 0.02268-1.9381 0.07203-1.1598 0.09954-2.3084 0.26952-3.4108 0.66115-1.0413 0.32357-1.9937 0.77464-2.7811 1.553-0.66771 0.6262-1.2491 1.3374-1.9404 1.9381 1.2373 0.03262 2.4793-0.01378 3.712 0.09787 0.08161 0.0074-0.02469 0.17515-0.08494 0.23068-0.03731 0.03439-0.0096-0.10235-1.85e-4 -0.15222 0.07511-0.39908 0.24315-0.78076 0.38022-1.1601 0.37962-0.92942 0.58939-1.8859 0.57777-2.896 0.01506-0.47523 0.04582-0.96424-0.0577-1.4334-0.10794-0.48914-0.37419-0.93937-0.40173-1.4497-0.15402-0.55207-0.32508-1.0754-0.57723-1.592-0.14541-0.29797-0.33208-0.5746-0.4773-0.87265-0.05226-0.10725-0.08657-0.22235-0.12986-0.33352l-3.9242 0.13069z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

5
verse/templates/forgotpassword.html → verse/statuspengguna/templates/statuspengguna/forgotpassword.html

@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "base/base.html" %}
{% block main %} {% block main %}
<div id="mainworkflow"> <div id="mainworkflow">
<div class="workflow"> <div class="workflow">
@ -6,7 +6,8 @@
<p> <p>
Enter the email address that was used to register with Distribusiverse. Enter the email address that was used to register with Distribusiverse.
</p> </p>
<form class="form" action="{{ url_for('forgotpassword') }}" method="post"> <form class="form" action="{{ url_for('forgotpassword.forgotpassword') }}"
method="post">
{{ forgotpasswordform.csrf_token }} {{ forgotpasswordform.csrf_token }}
<fieldset class="required"> <fieldset class="required">
{{ forgotpasswordform.email.label }} {{ forgotpasswordform.email.label }}

6
verse/templates/login.html → verse/statuspengguna/templates/statuspengguna/login.html

@ -1,7 +1,7 @@
{% extends "base.html" %} {% extends "base/base.html" %}
{% block main %} {% block main %}
<div id="login"> <div id="login">
<form class="form" action="{{ url_for('login') }}" method="post"> <form class="form" action="{{ url_for('login.login') }}" method="post">
{{ loginform.csrf_token }} {{ loginform.csrf_token }}
<fieldset class="required"> <fieldset class="required">
{{ loginform.email.label }} {{ loginform.email.label }}
@ -19,7 +19,7 @@
</fieldset> </fieldset>
<fieldset class="button required"> <fieldset class="button required">
{{ loginform.submit }} {{ loginform.submit }}
<a href="/forgotpassword">Forgot Password?</a> <a href="forgotpassword">Forgot Password?</a>
</fieldset> </fieldset>
</form> </form>
</div> </div>

4
verse/templates/register.html → verse/statuspengguna/templates/statuspengguna/register.html

@ -1,7 +1,7 @@
{% extends "base.html" %} {% extends "base/base.html" %}
{% block main %} {% block main %}
<div id="login"> <div id="login">
<form class="form" action="{{ url_for('register') }}" method="post"> <form class="form" action="{{ url_for('register.register') }}" method="post">
{{ registerform.csrf_token }} {{ registerform.csrf_token }}
<fieldset class="required"> <fieldset class="required">
{{ registerform.username.label }} {{ registerform.username.label }}

2
verse/templates/resetpassword.html → verse/statuspengguna/templates/statuspengguna/resetpassword.html

@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "base/base.html" %}
{% block main %} {% block main %}
<div id="login"> <div id="login">
{% if linkvalid%} {% if linkvalid%}

2
verse/templates/admin.html → verse/templates/base/admin.html

@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "base/base.html" %}
{% block main %} {% block main %}
<div id="buttons"> <div id="buttons">
<div class="overview"> <div class="overview">

0
verse/templates/base.html → verse/templates/base/base.html

0
verse/templates/filtermenu.html → verse/templates/base/filtermenu.html

2
verse/templates/help.html → verse/templates/base/help.html

@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "base/base.html" %}
{% block main %} {% block main %}
<div id="buttons"> <div id="buttons">
<div class="overview"> <div class="overview">

4
verse/templates/index.html → verse/templates/base/index.html

@ -1,4 +1,4 @@
{% extends "base.html" %} {% extends "base/base.html" %}
{% block main %} {% block main %}
<div id="buttons"> <div id="buttons">
@ -50,7 +50,7 @@
<!-- a div with all the distribusis listed in the distribusiverse --> <!-- a div with all the distribusis listed in the distribusiverse -->
<div id="distribusiverse" class="maincontent"> <div id="distribusiverse" class="maincontent">
<h2>List of distribusis</h2> <h2>List of distribusis</h2>
{% include 'filtermenu.html' %} {% include 'base/filtermenu.html' %}
<ul id="distribusi-index"> <ul id="distribusi-index">
{% for name, distribusi in distribusisindex.items() %} {% for name, distribusi in distribusisindex.items() %}
<li class='distribusi filter {{ distribusi["category"] }} {{ distribusi["year"] }} '> <li class='distribusi filter {{ distribusi["category"] }} {{ distribusi["year"] }} '>
Loading…
Cancel
Save