re-add yasi-applets
This commit is contained in:
10
src/yasi_applets/users/__init__.py
Normal file
10
src/yasi_applets/users/__init__.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from flask import Blueprint
|
||||
|
||||
bp = Blueprint('users', __name__,
|
||||
template_folder='',
|
||||
static_folder='static',
|
||||
static_url_path='/users/static')
|
||||
|
||||
|
||||
from yasi_applets.users import routes
|
||||
|
||||
BIN
src/yasi_applets/users/locales/af/LC_MESSAGES/users.mo
Normal file
BIN
src/yasi_applets/users/locales/af/LC_MESSAGES/users.mo
Normal file
Binary file not shown.
65
src/yasi_applets/users/locales/af/LC_MESSAGES/users.po
Normal file
65
src/yasi_applets/users/locales/af/LC_MESSAGES/users.po
Normal file
@@ -0,0 +1,65 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-20 15:48+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: routes.py:33
|
||||
msgid "Let's set up an initial user."
|
||||
msgstr "Kom on stel 'n gebruiker op."
|
||||
|
||||
msgid "Users"
|
||||
msgstr "Gebruikers"
|
||||
|
||||
#: routes.py:34
|
||||
msgid "Full Name"
|
||||
msgstr "Volle Naam"
|
||||
|
||||
#: routes.py:35
|
||||
msgid "Username"
|
||||
msgstr "Gebruikersnaam"
|
||||
|
||||
#: routes.py:36
|
||||
msgid "This username is available"
|
||||
msgstr "Hierdie gebruikersnaam is nie beskikbaar nie."
|
||||
|
||||
#: routes.py:37
|
||||
msgid "This username is not available"
|
||||
msgstr "Hierdie gebruikersnaam is nie beskikbaar nie."
|
||||
|
||||
#: routes.py:38
|
||||
msgid "This username is reserved by the system"
|
||||
msgstr "Hierdie gebruikersnaam is reserveerd deur vir die sisteem."
|
||||
|
||||
#: routes.py:39
|
||||
msgid "The username must be one word, lowercase, with no special characters"
|
||||
msgstr "Die gebruikersnaam moet een woord wees, kleinletters, met geen spesiale karakters."
|
||||
|
||||
#: routes.py:40
|
||||
msgid "Password"
|
||||
msgstr "Wagwoord"
|
||||
|
||||
#: routes.py:41
|
||||
msgid "Password (confirm)"
|
||||
msgstr "Wagwoord (bevestig)"
|
||||
|
||||
#: routes.py:42
|
||||
msgid "These passwords do now match"
|
||||
msgstr "Hierdie wagwoorde is nie dieselfde nie"
|
||||
|
||||
#: routes.py:43
|
||||
msgid "This password is too short"
|
||||
msgstr "Hierdie wagwoord is te kort"
|
||||
62
src/yasi_applets/users/locales/users.pot
Normal file
62
src/yasi_applets/users/locales/users.pot
Normal file
@@ -0,0 +1,62 @@
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-06-20 15:48+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: routes.py:33
|
||||
msgid "Let's set up an initial user."
|
||||
msgstr ""
|
||||
|
||||
#: routes.py:34
|
||||
msgid "Full Name"
|
||||
msgstr ""
|
||||
|
||||
#: routes.py:35
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#: routes.py:36
|
||||
msgid "This username is available"
|
||||
msgstr ""
|
||||
|
||||
#: routes.py:37
|
||||
msgid "This username is not available"
|
||||
msgstr ""
|
||||
|
||||
#: routes.py:38
|
||||
msgid "This username is reserved by the system"
|
||||
msgstr ""
|
||||
|
||||
#: routes.py:39
|
||||
msgid "The username must be one word, lowercase, with no special characters"
|
||||
msgstr ""
|
||||
|
||||
#: routes.py:40
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#: routes.py:41
|
||||
msgid "Password (confirm)"
|
||||
msgstr ""
|
||||
|
||||
#: routes.py:42
|
||||
msgid "These passwords do now match"
|
||||
msgstr ""
|
||||
|
||||
#: routes.py:43
|
||||
msgid "This password is too short"
|
||||
msgstr ""
|
||||
126
src/yasi_applets/users/routes.py
Normal file
126
src/yasi_applets/users/routes.py
Normal file
@@ -0,0 +1,126 @@
|
||||
from yasi_applets.software import bp
|
||||
from flask import Flask, request, session, redirect, \
|
||||
url_for, render_template, flash, Blueprint
|
||||
import gettext
|
||||
# we use this neat little trick to get config data from the main app
|
||||
from flask import current_app
|
||||
|
||||
# Set up Gettext
|
||||
def set_language(LANG):
|
||||
"""
|
||||
Sets language for this applet
|
||||
"""
|
||||
translations = gettext.translation("users", './applets/users/locales',
|
||||
fallback=True, languages=[LANG])
|
||||
translations.install()
|
||||
_ = translations.gettext
|
||||
|
||||
set_language('')
|
||||
|
||||
|
||||
@bp.route('/users')
|
||||
def users_root():
|
||||
"""
|
||||
Users screen for the webui.
|
||||
"""
|
||||
set_language(current_app.config['CONFIG']['settings']['language'])
|
||||
string_dict = build_stringlist()
|
||||
build_menu()
|
||||
menu = current_app.config['CONFIG']['settings']['menu_order'].split(" ")
|
||||
next_step_url = menu[menu.index("users")+1]
|
||||
if menu[menu.index("users")] == 1:
|
||||
previous_step_url = False
|
||||
else:
|
||||
previous_step_url = menu[menu.index("users")-1]
|
||||
|
||||
root_button = ' <button class="button not-allowed is-light"> <i class="fa fa-user" aria-hidden="true"></i> Setup root user </button>'
|
||||
ldap_button = ' <button class="button is-light"> <i class="fa fa-address-card" aria-hidden="true"></i> Connect LDAP </button>'
|
||||
ad_button = ' <button class="button is-light"> <i class="fa fa-address-card" aria-hidden="true"></i> Connect AD </button>'
|
||||
csv_button = ' <button class="button is-light"> <i class="fa fa-users" aria-hidden="true"></i> Import CSV </button>'
|
||||
bottom_menu = root_button + ldap_button + ad_button + csv_button
|
||||
bottom_menu = ""
|
||||
|
||||
initial_user = current_app.config['CONFIG']['recipe']['users']['users'][0]
|
||||
|
||||
build_summary()
|
||||
|
||||
return render_template('users.html', string_dict=string_dict,
|
||||
menu=current_app.config['CONFIG']['settings']['menu'],
|
||||
menu_order=current_app.config['CONFIG']['settings']['menu_order'].split(),
|
||||
previous_step=previous_step_url,
|
||||
next_step=next_step_url,
|
||||
bottom_menu=bottom_menu,
|
||||
initial_user=initial_user)
|
||||
|
||||
|
||||
@bp.route('/users/user-check/', methods=['GET', 'POST', 'PUT'])
|
||||
def check_user():
|
||||
if request.method == 'POST':
|
||||
username = request.form["username"]
|
||||
fullname = request.form["fullname"]
|
||||
current_app.config['CONFIG']['recipe']['users']['users'][0]['username'] = username
|
||||
current_app.config['CONFIG']['recipe']['users']['users'][0]['fullname'] = fullname
|
||||
if username in ["root", "games"]:
|
||||
return('<p class="has-text-danger"><b>That username is not available</b> </p>')
|
||||
else:
|
||||
return('<p class="has-text-success"><b>That username is available</b> </p>')
|
||||
build_summary()
|
||||
return("")
|
||||
|
||||
|
||||
@bp.route('/users/password-check/', methods=['GET', 'POST', 'PUT'])
|
||||
def check_password():
|
||||
if request.method == 'POST':
|
||||
password = request.form["password"]
|
||||
password_confirm = request.form["password_confirm"]
|
||||
current_app.config['CONFIG']['recipe']['users']['users'][0]['password'] = password
|
||||
current_app.config['CONFIG']['recipe']['users']['users'][0]['password_confirm'] = password_confirm
|
||||
if password != password_confirm:
|
||||
return('<p class="has-text-danger"><b>Passwords do not match</b> </p>')
|
||||
else:
|
||||
return('<p class="has-text-success"><b>Passwords match</b> </p>')
|
||||
build_summary()
|
||||
return("")
|
||||
|
||||
|
||||
def build_stringlist():
|
||||
"""
|
||||
Return all the strings that is used in this applet.
|
||||
"""
|
||||
string_dict = {}
|
||||
string_dict['menu_item'] = _("Users")
|
||||
string_dict['initial_user_text'] = _("Let's set up an initial user.")
|
||||
string_dict['full_name'] = _("Full Name")
|
||||
string_dict['user_name'] = _("Username")
|
||||
string_dict['user_name_hint'] = _("One word, all lowercase")
|
||||
string_dict['user_name_available'] = _("This username is available")
|
||||
string_dict['user_name_not_available'] = _("This username is not available")
|
||||
string_dict['user_name_reserved'] = _("This username is reserved by the system")
|
||||
string_dict['user_name_characters'] = _("The username must be one word, lowercase, with no special characters")
|
||||
string_dict['password'] = _("Password")
|
||||
string_dict['password_confirm'] = _("Password (confirm)")
|
||||
string_dict['password_nomatch'] = _("These passwords do now match")
|
||||
string_dict['password_tooshort'] = _("This password is too short")
|
||||
return string_dict
|
||||
|
||||
|
||||
def build_menu():
|
||||
"""
|
||||
Define menu items and paths.
|
||||
"""
|
||||
current_app.config['CONFIG']['settings']['menu']['users'] = (build_stringlist()['menu_item'], "/users", 20)
|
||||
print(current_app.config['CONFIG']['settings']['menu'])
|
||||
|
||||
|
||||
def build_summary():
|
||||
"""
|
||||
Write up a summary of what this module will do.
|
||||
"""
|
||||
current_app.config['CONFIG']['Summary']['users'] = {}
|
||||
current_app.config['CONFIG']['Summary']['users']['heading'] = "Users and Identity"
|
||||
current_app.config['CONFIG']['Summary']['users']['bleh'] = current_app.config['CONFIG']['recipe']['popcon']['enable_popcon']
|
||||
current_app.config['CONFIG']['Summary']['users']['settings'] = current_app.config['CONFIG']['recipe']['users']['users']
|
||||
current_app.config['CONFIG']['Summary']['users']['text'] = "Add primary user with the username: " + str(current_app.config['CONFIG']['recipe']['users']['users'][0]['username'])
|
||||
return("ok?")
|
||||
|
||||
build_menu()
|
||||
24
src/yasi_applets/users/routes.py.bak
Normal file
24
src/yasi_applets/users/routes.py.bak
Normal file
@@ -0,0 +1,24 @@
|
||||
from applets.software import bp
|
||||
from flask import Flask, request, session, redirect, \
|
||||
url_for, render_template, flash, Blueprint
|
||||
# we use this neat little trick to get config data from the main app
|
||||
from flask import current_app
|
||||
|
||||
|
||||
def build_stringlist():
|
||||
"""
|
||||
Return all the strings that is used in this applet.
|
||||
"""
|
||||
string_dict = {}
|
||||
string_dict['initial_user_text'] = _("Let's set up an initial user.")
|
||||
string_dict['full_name'] = _("Full Name")
|
||||
string_dict['user_name'] = _("Username")
|
||||
string_dict['user_name_available'] = _("This username is available")
|
||||
string_dict['user_name_not_available'] = _("This username is not available")
|
||||
string_dict['user_name_reserved'] = _("This username is reserved by the system")
|
||||
string_dict['user_name_characters'] = _("The username must be one word, lowercase, with no special characters")
|
||||
string_dict['password'] = _("Password")
|
||||
string_dict['password_confirm'] = _("Password (confirm)")
|
||||
string_dict['password_nomatch'] = _("These passwords do now match")
|
||||
string_dict['password_tooshort'] = _("This password is too short")
|
||||
return string_dict
|
||||
22
src/yasi_applets/users/static/img/avatar-default.svg
Normal file
22
src/yasi_applets/users/static/img/avatar-default.svg
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg height="128px" viewBox="0 0 128 128" width="128px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<linearGradient id="a" gradientUnits="userSpaceOnUse" x1="16.98286657496" x2="113.51232281881" y1="91.79046347784" y2="91.79046347784">
|
||||
<stop offset="0" stop-color="#e6f0fc"/>
|
||||
<stop offset="0.0383542" stop-color="#cadff8" stop-opacity="0.996078"/>
|
||||
<stop offset="0.124655" stop-color="#d4e5f9" stop-opacity="0.992157"/>
|
||||
<stop offset="0.901364" stop-color="#b2d0f4" stop-opacity="0.964706"/>
|
||||
<stop offset="0.9589" stop-color="#d0e3f9" stop-opacity="0.964706"/>
|
||||
<stop offset="1" stop-color="#98c1f1" stop-opacity="0.964706"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="b" gradientUnits="userSpaceOnUse" x1="35.05556157496" x2="88.56691281881" y1="91.79046347784" y2="91.79046347784">
|
||||
<stop offset="0" stop-color="#e6f0fc"/>
|
||||
<stop offset="0.230125" stop-color="#cadff8" stop-opacity="0.996078"/>
|
||||
<stop offset="0.383542" stop-color="#d4e5f9" stop-opacity="0.992157"/>
|
||||
<stop offset="0.588996" stop-color="#b2d0f4" stop-opacity="0.964706"/>
|
||||
<stop offset="0.753397" stop-color="#d0e3f9" stop-opacity="0.964706"/>
|
||||
<stop offset="1" stop-color="#98c1f1" stop-opacity="0.964706"/>
|
||||
</linearGradient>
|
||||
<path d="m 65.007812 67.363281 c -24.257812 0.027344 -44.703124 16.957031 -49.898437 39.847657 c -1.597656 5.96875 1.65625 9.007812 5.269531 9.007812 h 88.402344 c 4.75 0 7.4375 -4.191406 6.222656 -8.734375 c -5.097656 -23.042969 -25.625 -40.109375 -49.996094 -40.121094 z m 0 0" fill="url(#a)"/>
|
||||
<path d="m 89.351562 33.375 c 0 14.257812 -11.554687 25.8125 -25.8125 25.8125 c -14.257812 0 -25.816406 -11.554688 -25.816406 -25.8125 s 11.558594 -25.816406 25.816406 -25.816406 c 14.257813 0 25.8125 11.558594 25.8125 25.816406 z m 0 0" fill="url(#b)"/>
|
||||
<path d="m 65.007812 64.082031 c -24.257812 0.03125 -44.703124 16.074219 -49.898437 38.96875 c -1.597656 5.96875 1.65625 9.007813 5.269531 9.007813 h 88.402344 c 4.75 0 7.4375 -4.191406 6.222656 -8.734375 c -5.097656 -23.042969 -25.625 -39.226563 -49.996094 -39.242188 z m 24.34375 -34.046875 c 0 14.257813 -11.554687 25.8125 -25.8125 25.8125 c -14.257812 0 -25.816406 -11.554687 -25.816406 -25.8125 c 0 -14.257812 11.558594 -25.816406 25.816406 -25.816406 c 14.257813 0 25.8125 11.558594 25.8125 25.816406 z m 0 0" fill="#f6f9fe" fill-opacity="0.996078"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
73
src/yasi_applets/users/users.html
Normal file
73
src/yasi_applets/users/users.html
Normal file
@@ -0,0 +1,73 @@
|
||||
{% extends "layout.html" %}
|
||||
{% block body %}
|
||||
|
||||
<p><b> {{ string_dict['initial_user_text'] }} </b></p>
|
||||
|
||||
<br>
|
||||
|
||||
<form action="/users" method="POST">
|
||||
|
||||
<img src="/users/static/img/avatar-default.svg" width="160px" style="float: left; position: absolute;" />
|
||||
|
||||
<div style="margin-left: 180px;">
|
||||
|
||||
<div class="field">
|
||||
<label>{{ string_dict['full_name'] }}</label>
|
||||
<div class="control has-icons-left has-icons-right">
|
||||
<input class="input" name="fullname" type="text" placeholder="Full Name" value="{% if initial_user['fullname'] %}{{ initial_user['fullname'] }}{% endif %}" hx-post="/users/user-check" hx-trigger="keyup changed delay:500ms" hx-target="#username-name">
|
||||
<span class="icon is-small is-left">
|
||||
<i class="fa fa-user-circle-o" aria-hidden="true"></i>
|
||||
</span>
|
||||
<!-- <span class="icon is-small is-right">
|
||||
<img src="/static/icons/emblem-default-symbolic.svg">
|
||||
</span> -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label>{{ string_dict['user_name'] }}</label>
|
||||
<div class="control has-icons-left has-icons-right">
|
||||
<input class="input" type="text" placeholder="{{ string_dict['user_name'] }}" value="{% if initial_user['username'] %}{{ initial_user['username'] }}{% endif %}" name="username" hx-post="/users/user-check" hx-trigger="keyup changed delay:200ms" hx-trigger="load" hx-target="#username-status">
|
||||
<span class="icon is-small is-left">
|
||||
<i class="fa fa-user-circle-o" aria-hidden="true"></i>
|
||||
</span>
|
||||
<!-- <span class="icon is-small is-right">
|
||||
<i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
|
||||
</span> -->
|
||||
</div>
|
||||
<div id="username-status">
|
||||
<p> {{ string_dict['user_name_hint'] }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="password">{{ string_dict['password'] }}</label>
|
||||
<div class="control has-icons-left has-icons-right">
|
||||
<input class="input" name="password" type="password" placeholder="{{ string_dict['password'] }}" value="{% if initial_user['password'] %}{{ initial_user['password'] }}{% endif %}" hx-post="/users/password-check" hx-trigger="keyup changed delay:200ms" hx-target="#password-status">
|
||||
<span class="icon is-small is-left">
|
||||
<i class="fa fa-address-card" aria-hidden="true"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<label class="password">{{ string_dict['password_confirm'] }}</label>
|
||||
<div class="control has-icons-left has-icons-right">
|
||||
<input class="input" name="password_confirm" type="password" placeholder="{{ string_dict['password_confirm'] }}" value="{% if initial_user['password_confirm'] %}{{ initial_user['password_confirm'] }}{% endif %}" hx-post="/users/password-check" hx-trigger="keyup changed delay:200ms" hx-target="#password-status">
|
||||
<span class="icon is-small is-left">
|
||||
<i class="fa fa-address-card" aria-hidden="true"></i>
|
||||
</span>
|
||||
<div id="password-status">
|
||||
<p> </p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</div> <!-- style 180 -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user