ivoryos 0.1.9__py3-none-any.whl → 0.1.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ivoryos might be problematic. Click here for more details.
- ivoryos/__init__.py +118 -99
- ivoryos/config.py +47 -47
- ivoryos/routes/auth/auth.py +100 -65
- ivoryos/routes/auth/templates/auth/login.html +25 -25
- ivoryos/routes/auth/templates/auth/signup.html +32 -32
- ivoryos/routes/control/control.py +400 -272
- ivoryos/routes/control/templates/control/controllers.html +75 -75
- ivoryos/routes/control/templates/control/controllers_home.html +50 -50
- ivoryos/routes/control/templates/control/controllers_new.html +89 -89
- ivoryos/routes/database/database.py +188 -114
- ivoryos/routes/database/templates/database/experiment_database.html +72 -72
- ivoryos/routes/design/design.py +541 -416
- ivoryos/routes/design/templates/design/experiment_builder.html +415 -415
- ivoryos/routes/design/templates/design/experiment_run.html +325 -325
- ivoryos/routes/main/main.py +42 -25
- ivoryos/routes/main/templates/main/help.html +141 -141
- ivoryos/routes/main/templates/main/home.html +68 -68
- ivoryos/static/.DS_Store +0 -0
- ivoryos/static/js/overlay.js +12 -12
- ivoryos/static/js/socket_handler.js +34 -34
- ivoryos/static/js/sortable_card.js +24 -24
- ivoryos/static/js/sortable_design.js +36 -36
- ivoryos/static/style.css +201 -201
- ivoryos/templates/base.html +143 -143
- ivoryos/utils/db_models.py +518 -518
- ivoryos/utils/form.py +316 -316
- ivoryos/utils/global_config.py +67 -67
- ivoryos/utils/llm_agent.py +183 -183
- ivoryos/utils/script_runner.py +165 -164
- ivoryos/utils/utils.py +425 -422
- ivoryos/version.py +1 -0
- {ivoryos-0.1.9.dist-info → ivoryos-0.1.10.dist-info}/LICENSE +21 -21
- {ivoryos-0.1.9.dist-info → ivoryos-0.1.10.dist-info}/METADATA +170 -169
- ivoryos-0.1.10.dist-info/RECORD +47 -0
- {ivoryos-0.1.9.dist-info → ivoryos-0.1.10.dist-info}/WHEEL +1 -1
- ivoryos-0.1.9.dist-info/RECORD +0 -45
- {ivoryos-0.1.9.dist-info → ivoryos-0.1.10.dist-info}/top_level.txt +0 -0
ivoryos/__init__.py
CHANGED
|
@@ -1,99 +1,118 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import sys
|
|
3
|
-
from typing import Union
|
|
4
|
-
|
|
5
|
-
from flask import Flask, redirect, url_for
|
|
6
|
-
|
|
7
|
-
from ivoryos.config import Config, get_config
|
|
8
|
-
from ivoryos.routes.auth.auth import auth, login_manager
|
|
9
|
-
from ivoryos.routes.control.control import control
|
|
10
|
-
from ivoryos.routes.database.database import database
|
|
11
|
-
from ivoryos.routes.design.design import design, socketio
|
|
12
|
-
from ivoryos.routes.main.main import main
|
|
13
|
-
from ivoryos.utils import utils
|
|
14
|
-
from ivoryos.utils.db_models import db
|
|
15
|
-
from ivoryos.utils.global_config import GlobalConfig
|
|
16
|
-
from ivoryos.utils.script_runner import ScriptRunner
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
#
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
app.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
app.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
from typing import Union
|
|
4
|
+
|
|
5
|
+
from flask import Flask, redirect, url_for
|
|
6
|
+
|
|
7
|
+
from ivoryos.config import Config, get_config
|
|
8
|
+
from ivoryos.routes.auth.auth import auth, login_manager
|
|
9
|
+
from ivoryos.routes.control.control import control
|
|
10
|
+
from ivoryos.routes.database.database import database
|
|
11
|
+
from ivoryos.routes.design.design import design, socketio
|
|
12
|
+
from ivoryos.routes.main.main import main
|
|
13
|
+
from ivoryos.utils import utils
|
|
14
|
+
from ivoryos.utils.db_models import db
|
|
15
|
+
from ivoryos.utils.global_config import GlobalConfig
|
|
16
|
+
from ivoryos.utils.script_runner import ScriptRunner
|
|
17
|
+
from ivoryos.version import __version__ as ivoryos_version
|
|
18
|
+
|
|
19
|
+
global_config = GlobalConfig()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
url_prefix = os.getenv('URL_PREFIX', "/ivoryos")
|
|
23
|
+
app = Flask(__name__, static_url_path=f'{url_prefix}/static', static_folder='static')
|
|
24
|
+
app.register_blueprint(main, url_prefix=url_prefix)
|
|
25
|
+
app.register_blueprint(auth, url_prefix=url_prefix)
|
|
26
|
+
app.register_blueprint(design, url_prefix=url_prefix)
|
|
27
|
+
app.register_blueprint(database, url_prefix=url_prefix)
|
|
28
|
+
app.register_blueprint(control, url_prefix=url_prefix)
|
|
29
|
+
|
|
30
|
+
def create_app(config_class=None):
|
|
31
|
+
# url_prefix = os.getenv('URL_PREFIX', "/ivoryos")
|
|
32
|
+
# app = Flask(__name__, static_url_path=f'{url_prefix}/static', static_folder='static')
|
|
33
|
+
app.config.from_object(config_class or 'config.get_config()')
|
|
34
|
+
|
|
35
|
+
# Initialize extensions
|
|
36
|
+
socketio.init_app(app)
|
|
37
|
+
login_manager.init_app(app)
|
|
38
|
+
login_manager.login_view = "auth.login"
|
|
39
|
+
db.init_app(app)
|
|
40
|
+
|
|
41
|
+
# Create database tables
|
|
42
|
+
with app.app_context():
|
|
43
|
+
db.create_all()
|
|
44
|
+
|
|
45
|
+
# Additional setup
|
|
46
|
+
utils.create_gui_dir(app.config['OUTPUT_FOLDER'])
|
|
47
|
+
|
|
48
|
+
# logger_list = app.config["LOGGERS"]
|
|
49
|
+
logger_path = os.path.join(app.config["OUTPUT_FOLDER"], app.config["LOGGERS_PATH"])
|
|
50
|
+
logger = utils.start_logger(socketio, 'gui_logger', logger_path)
|
|
51
|
+
|
|
52
|
+
@app.before_request
|
|
53
|
+
def before_request():
|
|
54
|
+
from flask import g
|
|
55
|
+
g.logger = logger
|
|
56
|
+
g.socketio = socketio
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@app.route('/')
|
|
61
|
+
def redirect_to_prefix():
|
|
62
|
+
return redirect(url_for('main.index', version=ivoryos_version)) # Assuming 'index' is a route in your blueprint
|
|
63
|
+
|
|
64
|
+
return app
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def run(module=None, host="0.0.0.0", port=None, debug=None, llm_server=None, model=None,
|
|
68
|
+
config: Config = None,
|
|
69
|
+
logger: Union[str, list] = None,
|
|
70
|
+
logger_output_name: str = None,
|
|
71
|
+
):
|
|
72
|
+
"""
|
|
73
|
+
Start ivoryOS app server.
|
|
74
|
+
|
|
75
|
+
:param module: module name, __name__ for current module
|
|
76
|
+
:param host: host address, defaults to 0.0.0.0
|
|
77
|
+
:param port: port, defaults to None, and will use 8000
|
|
78
|
+
:param debug: debug mode, defaults to None (True)
|
|
79
|
+
:param llm_server: llm server, defaults to None.
|
|
80
|
+
:param model: llm model, defaults to None. If None, app will run without text-to-code feature
|
|
81
|
+
:param config: config class, defaults to None
|
|
82
|
+
:param logger: logger name of list of logger names, defaults to None
|
|
83
|
+
:param logger_output_name: log file save name of logger, defaults to None, and will use "default.log"
|
|
84
|
+
|
|
85
|
+
"""
|
|
86
|
+
app = create_app(config_class=config or get_config()) # Create app instance using factory function
|
|
87
|
+
|
|
88
|
+
port = port or int(os.environ.get("PORT", 8000))
|
|
89
|
+
debug = debug if debug is not None else app.config.get('DEBUG', True)
|
|
90
|
+
|
|
91
|
+
app.config["LOGGERS"] = logger
|
|
92
|
+
app.config["LOGGERS_PATH"] = logger_output_name or app.config["LOGGERS_PATH"] # default.log
|
|
93
|
+
logger_path = os.path.join(app.config["OUTPUT_FOLDER"], app.config["LOGGERS_PATH"])
|
|
94
|
+
|
|
95
|
+
if module:
|
|
96
|
+
app.config["MODULE"] = module
|
|
97
|
+
app.config["OFF_LINE"] = False
|
|
98
|
+
global_config.deck = sys.modules[module]
|
|
99
|
+
global_config.deck_snapshot = utils.create_deck_snapshot(global_config.deck, output_path=app.config["DUMMY_DECK"], save=True)
|
|
100
|
+
# global_config.runner = ScriptRunner(globals())
|
|
101
|
+
else:
|
|
102
|
+
app.config["OFF_LINE"] = True
|
|
103
|
+
if model:
|
|
104
|
+
app.config["ENABLE_LLM"] = True
|
|
105
|
+
app.config["LLM_MODEL"] = model
|
|
106
|
+
app.config["LLM_SERVER"] = llm_server
|
|
107
|
+
utils.install_and_import('openai')
|
|
108
|
+
from ivoryos.utils.llm_agent import LlmAgent
|
|
109
|
+
global_config.agent = LlmAgent(host=llm_server, model=model,
|
|
110
|
+
output_path=app.config["OUTPUT_FOLDER"] if module is not None else None)
|
|
111
|
+
else:
|
|
112
|
+
app.config["ENABLE_LLM"] = False
|
|
113
|
+
if logger and type(logger) is str:
|
|
114
|
+
utils.start_logger(socketio, log_filename=logger_path, logger_name=logger)
|
|
115
|
+
elif type(logger) is list:
|
|
116
|
+
for log in logger:
|
|
117
|
+
utils.start_logger(socketio, log_filename=logger_path, logger_name=log)
|
|
118
|
+
socketio.run(app, host=host, port=port, debug=debug, use_reloader=False, allow_unsafe_werkzeug=True)
|
ivoryos/config.py
CHANGED
|
@@ -1,47 +1,47 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from dotenv import load_dotenv
|
|
3
|
-
|
|
4
|
-
# Load environment variables from .env file
|
|
5
|
-
load_dotenv()
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class Config:
|
|
9
|
-
SECRET_KEY = os.getenv('SECRET_KEY', 'default_secret_key')
|
|
10
|
-
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY', None)
|
|
11
|
-
|
|
12
|
-
OUTPUT_FOLDER = os.path.join(os.path.abspath(os.curdir), 'ivoryos_data')
|
|
13
|
-
os.makedirs(OUTPUT_FOLDER, exist_ok=True)
|
|
14
|
-
CSV_FOLDER = os.path.join(OUTPUT_FOLDER, 'config_csv/')
|
|
15
|
-
SCRIPT_FOLDER = os.path.join(OUTPUT_FOLDER, 'scripts/')
|
|
16
|
-
DATA_FOLDER = os.path.join(OUTPUT_FOLDER, 'results/')
|
|
17
|
-
DUMMY_DECK = os.path.join(OUTPUT_FOLDER, 'pseudo_deck/')
|
|
18
|
-
LLM_OUTPUT = os.path.join(OUTPUT_FOLDER, 'llm_output/')
|
|
19
|
-
DECK_HISTORY = os.path.join(OUTPUT_FOLDER, 'deck_history.txt')
|
|
20
|
-
LOGGERS_PATH = "default.log"
|
|
21
|
-
|
|
22
|
-
SQLALCHEMY_DATABASE_URI = f"sqlite:///{os.path.join(OUTPUT_FOLDER, 'ivoryos.db')}"
|
|
23
|
-
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
|
24
|
-
|
|
25
|
-
ENABLE_LLM = True if OPENAI_API_KEY else False
|
|
26
|
-
OFF_LINE = True
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
class DevelopmentConfig(Config):
|
|
30
|
-
DEBUG = True
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
class ProductionConfig(Config):
|
|
34
|
-
DEBUG = False
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
class TestingConfig(Config):
|
|
38
|
-
DEBUG = True
|
|
39
|
-
TESTING = True
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def get_config(env='dev'):
|
|
43
|
-
if env == 'production':
|
|
44
|
-
return ProductionConfig()
|
|
45
|
-
elif env == 'testing':
|
|
46
|
-
return TestingConfig()
|
|
47
|
-
return DevelopmentConfig()
|
|
1
|
+
import os
|
|
2
|
+
from dotenv import load_dotenv
|
|
3
|
+
|
|
4
|
+
# Load environment variables from .env file
|
|
5
|
+
load_dotenv()
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Config:
|
|
9
|
+
SECRET_KEY = os.getenv('SECRET_KEY', 'default_secret_key')
|
|
10
|
+
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY', None)
|
|
11
|
+
|
|
12
|
+
OUTPUT_FOLDER = os.path.join(os.path.abspath(os.curdir), 'ivoryos_data')
|
|
13
|
+
os.makedirs(OUTPUT_FOLDER, exist_ok=True)
|
|
14
|
+
CSV_FOLDER = os.path.join(OUTPUT_FOLDER, 'config_csv/')
|
|
15
|
+
SCRIPT_FOLDER = os.path.join(OUTPUT_FOLDER, 'scripts/')
|
|
16
|
+
DATA_FOLDER = os.path.join(OUTPUT_FOLDER, 'results/')
|
|
17
|
+
DUMMY_DECK = os.path.join(OUTPUT_FOLDER, 'pseudo_deck/')
|
|
18
|
+
LLM_OUTPUT = os.path.join(OUTPUT_FOLDER, 'llm_output/')
|
|
19
|
+
DECK_HISTORY = os.path.join(OUTPUT_FOLDER, 'deck_history.txt')
|
|
20
|
+
LOGGERS_PATH = "default.log"
|
|
21
|
+
|
|
22
|
+
SQLALCHEMY_DATABASE_URI = f"sqlite:///{os.path.join(OUTPUT_FOLDER, 'ivoryos.db')}"
|
|
23
|
+
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
|
24
|
+
|
|
25
|
+
ENABLE_LLM = True if OPENAI_API_KEY else False
|
|
26
|
+
OFF_LINE = True
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class DevelopmentConfig(Config):
|
|
30
|
+
DEBUG = True
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class ProductionConfig(Config):
|
|
34
|
+
DEBUG = False
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class TestingConfig(Config):
|
|
38
|
+
DEBUG = True
|
|
39
|
+
TESTING = True
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def get_config(env='dev'):
|
|
43
|
+
if env == 'production':
|
|
44
|
+
return ProductionConfig()
|
|
45
|
+
elif env == 'testing':
|
|
46
|
+
return TestingConfig()
|
|
47
|
+
return DevelopmentConfig()
|
ivoryos/routes/auth/auth.py
CHANGED
|
@@ -1,65 +1,100 @@
|
|
|
1
|
-
from flask import Blueprint, redirect, url_for, flash, request, render_template, session
|
|
2
|
-
from flask_login import login_required, login_user, logout_user, LoginManager
|
|
3
|
-
import bcrypt
|
|
4
|
-
|
|
5
|
-
from ivoryos.utils.db_models import Script, User, db
|
|
6
|
-
from ivoryos.utils.utils import post_script_file
|
|
7
|
-
login_manager = LoginManager()
|
|
8
|
-
|
|
9
|
-
auth = Blueprint('auth', __name__, template_folder='templates/auth')
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
@auth.route('/login', methods=['GET', 'POST'])
|
|
13
|
-
def login():
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return redirect(url_for('auth.login'))
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
1
|
+
from flask import Blueprint, redirect, url_for, flash, request, render_template, session
|
|
2
|
+
from flask_login import login_required, login_user, logout_user, LoginManager
|
|
3
|
+
import bcrypt
|
|
4
|
+
|
|
5
|
+
from ivoryos.utils.db_models import Script, User, db
|
|
6
|
+
from ivoryos.utils.utils import post_script_file
|
|
7
|
+
login_manager = LoginManager()
|
|
8
|
+
|
|
9
|
+
auth = Blueprint('auth', __name__, template_folder='templates/auth')
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@auth.route('/login', methods=['GET', 'POST'])
|
|
13
|
+
def login():
|
|
14
|
+
"""
|
|
15
|
+
.. :quickref: User; login user
|
|
16
|
+
|
|
17
|
+
.. http:get:: /login
|
|
18
|
+
|
|
19
|
+
load user login form.
|
|
20
|
+
|
|
21
|
+
.. http:post:: /login
|
|
22
|
+
|
|
23
|
+
:form username: username
|
|
24
|
+
:form password: password
|
|
25
|
+
:status 302: and then redirects to homepage
|
|
26
|
+
:status 401: incorrect password, redirects to :http:get:`/ivoryos/login`
|
|
27
|
+
"""
|
|
28
|
+
if request.method == 'POST':
|
|
29
|
+
username = request.form.get('username')
|
|
30
|
+
password = request.form.get('password')
|
|
31
|
+
|
|
32
|
+
# session.query(User, User.name).all()
|
|
33
|
+
user = db.session.query(User).filter(User.username == username).first()
|
|
34
|
+
input_password = password.encode('utf-8')
|
|
35
|
+
# if user and bcrypt.checkpw(input_password, user.hashPassword.encode('utf-8')):
|
|
36
|
+
if user and bcrypt.checkpw(input_password, user.hashPassword):
|
|
37
|
+
# password.encode("utf-8")
|
|
38
|
+
# user = User(username, password.encode("utf-8"))
|
|
39
|
+
login_user(user)
|
|
40
|
+
session['user'] = username
|
|
41
|
+
script_file = Script(author=username)
|
|
42
|
+
session["script"] = script_file.as_dict()
|
|
43
|
+
session['hidden_functions'], session['card_order'], session['prompt'] = {}, {}, {}
|
|
44
|
+
session['autofill'] = False
|
|
45
|
+
post_script_file(script_file)
|
|
46
|
+
return redirect(url_for('main.index'))
|
|
47
|
+
else:
|
|
48
|
+
flash("Incorrect username or password")
|
|
49
|
+
return redirect(url_for('auth.login')), 401
|
|
50
|
+
return render_template('login.html')
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@auth.route('/signup', methods=['GET', 'POST'])
|
|
54
|
+
def signup():
|
|
55
|
+
"""
|
|
56
|
+
.. :quickref: User; signup for a new account
|
|
57
|
+
|
|
58
|
+
.. http:get:: /signup
|
|
59
|
+
|
|
60
|
+
load user sighup
|
|
61
|
+
|
|
62
|
+
.. http:post:: /signup
|
|
63
|
+
|
|
64
|
+
:form username: username
|
|
65
|
+
:form password: password
|
|
66
|
+
:status 302: and then redirects to :http:get:`/ivoryos/login`
|
|
67
|
+
:status 409: when user already exists, redirects to :http:get:`/ivoryos/signup`
|
|
68
|
+
"""
|
|
69
|
+
if request.method == 'POST':
|
|
70
|
+
username = request.form.get('username')
|
|
71
|
+
password = request.form.get('password')
|
|
72
|
+
salt = bcrypt.gensalt()
|
|
73
|
+
hashed = bcrypt.hashpw(password.encode('utf-8'), salt)
|
|
74
|
+
user = User(username, hashed)
|
|
75
|
+
try:
|
|
76
|
+
db.session.add(user)
|
|
77
|
+
db.session.commit()
|
|
78
|
+
return redirect(url_for('auth.login'))
|
|
79
|
+
except Exception:
|
|
80
|
+
flash("username exists :(", "error")
|
|
81
|
+
return render_template('signup.html'), 409
|
|
82
|
+
return render_template('signup.html')
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@auth.route("/logout")
|
|
86
|
+
@login_required
|
|
87
|
+
def logout():
|
|
88
|
+
"""
|
|
89
|
+
.. :quickref: User; logout the user
|
|
90
|
+
|
|
91
|
+
logout the current user, clear session info, and redirect to the login page.
|
|
92
|
+
"""
|
|
93
|
+
logout_user()
|
|
94
|
+
session.clear()
|
|
95
|
+
return redirect(url_for('auth.login'))
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
@login_manager.user_loader
|
|
99
|
+
def load_user(username):
|
|
100
|
+
return User(username, password=None)
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
{% extends 'base.html' %}
|
|
2
|
-
{% block title %}IvoryOS | Login{% endblock %}
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
{% block body %}
|
|
6
|
-
<div class= "login">
|
|
7
|
-
<div class="bg-white rounded shadow-sm flex-fill">
|
|
8
|
-
<div class="p-4" style="align-items: center">
|
|
9
|
-
<h5>Log in</h5>
|
|
10
|
-
<form role="form" method='POST' name="login" action="{{ url_for('auth.login') }}">
|
|
11
|
-
<div class="input-group mb-3">
|
|
12
|
-
<label class="input-group-text" for="username">Username</label>
|
|
13
|
-
<input class="form-control" type="text" id="username" name="username">
|
|
14
|
-
</div>
|
|
15
|
-
<div class="input-group mb-3">
|
|
16
|
-
<label class="input-group-text" for="password">Password</label>
|
|
17
|
-
<input class="form-control" type="password" id="password" name="password">
|
|
18
|
-
</div>
|
|
19
|
-
<button type="submit" class="btn btn-secondary" name="login" style="width: 100%;">login</button>
|
|
20
|
-
</form>
|
|
21
|
-
<p class="message">Not registered? <a href="{{ url_for('auth.signup') }}">Create a new account</a>
|
|
22
|
-
</div>
|
|
23
|
-
</div>
|
|
24
|
-
</div>
|
|
25
|
-
{% endblock %}
|
|
1
|
+
{% extends 'base.html' %}
|
|
2
|
+
{% block title %}IvoryOS | Login{% endblock %}
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
{% block body %}
|
|
6
|
+
<div class= "login">
|
|
7
|
+
<div class="bg-white rounded shadow-sm flex-fill">
|
|
8
|
+
<div class="p-4" style="align-items: center">
|
|
9
|
+
<h5>Log in</h5>
|
|
10
|
+
<form role="form" method='POST' name="login" action="{{ url_for('auth.login') }}">
|
|
11
|
+
<div class="input-group mb-3">
|
|
12
|
+
<label class="input-group-text" for="username">Username</label>
|
|
13
|
+
<input class="form-control" type="text" id="username" name="username">
|
|
14
|
+
</div>
|
|
15
|
+
<div class="input-group mb-3">
|
|
16
|
+
<label class="input-group-text" for="password">Password</label>
|
|
17
|
+
<input class="form-control" type="password" id="password" name="password">
|
|
18
|
+
</div>
|
|
19
|
+
<button type="submit" class="btn btn-secondary" name="login" style="width: 100%;">login</button>
|
|
20
|
+
</form>
|
|
21
|
+
<p class="message">Not registered? <a href="{{ url_for('auth.signup') }}">Create a new account</a>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
{% endblock %}
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
{% extends 'base.html' %}
|
|
2
|
-
{% block title %}IvoryOS | Signup{% endblock %}
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
{% block body %}
|
|
6
|
-
<div class= "login">
|
|
7
|
-
<div class="bg-white rounded shadow-sm flex-fill">
|
|
8
|
-
<div class="p-4" style="align: center">
|
|
9
|
-
<h5>Create a new account</h5>
|
|
10
|
-
<form role="form" method='POST' name="signup" action="{{ url_for('auth.signup') }}">
|
|
11
|
-
|
|
12
|
-
<div class="input-group mb-3">
|
|
13
|
-
<label class="input-group-text" for="username">Username</label>
|
|
14
|
-
<input class="form-control" type="text" id="username" name="username" required>
|
|
15
|
-
</div>
|
|
16
|
-
<div class="input-group mb-3">
|
|
17
|
-
<label class="input-group-text" for="password">Password</label>
|
|
18
|
-
<input class="form-control" type="password" id="password" name="password" required>
|
|
19
|
-
</div>
|
|
20
|
-
{# <div class="input-group mb-3">#}
|
|
21
|
-
{# <label class="input-group-text" for="confirm_password">Confirm Password</label>#}
|
|
22
|
-
{# <input class="form-control" type="confirm_password" id="confirm_password" name="confirm_password">#}
|
|
23
|
-
{# </div>#}
|
|
24
|
-
|
|
25
|
-
<button type="submit" class="btn btn-secondary" name="login" style="width: 100%;">Sign up</button>
|
|
26
|
-
</form>
|
|
27
|
-
<p class="message" >Already registered? <a href="{{ url_for('auth.login') }}">Sign In</a></p>
|
|
28
|
-
</div>
|
|
29
|
-
</div>
|
|
30
|
-
</div>
|
|
31
|
-
|
|
32
|
-
{% endblock %}
|
|
1
|
+
{% extends 'base.html' %}
|
|
2
|
+
{% block title %}IvoryOS | Signup{% endblock %}
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
{% block body %}
|
|
6
|
+
<div class= "login">
|
|
7
|
+
<div class="bg-white rounded shadow-sm flex-fill">
|
|
8
|
+
<div class="p-4" style="align: center">
|
|
9
|
+
<h5>Create a new account</h5>
|
|
10
|
+
<form role="form" method='POST' name="signup" action="{{ url_for('auth.signup') }}">
|
|
11
|
+
|
|
12
|
+
<div class="input-group mb-3">
|
|
13
|
+
<label class="input-group-text" for="username">Username</label>
|
|
14
|
+
<input class="form-control" type="text" id="username" name="username" required>
|
|
15
|
+
</div>
|
|
16
|
+
<div class="input-group mb-3">
|
|
17
|
+
<label class="input-group-text" for="password">Password</label>
|
|
18
|
+
<input class="form-control" type="password" id="password" name="password" required>
|
|
19
|
+
</div>
|
|
20
|
+
{# <div class="input-group mb-3">#}
|
|
21
|
+
{# <label class="input-group-text" for="confirm_password">Confirm Password</label>#}
|
|
22
|
+
{# <input class="form-control" type="confirm_password" id="confirm_password" name="confirm_password">#}
|
|
23
|
+
{# </div>#}
|
|
24
|
+
|
|
25
|
+
<button type="submit" class="btn btn-secondary" name="login" style="width: 100%;">Sign up</button>
|
|
26
|
+
</form>
|
|
27
|
+
<p class="message" >Already registered? <a href="{{ url_for('auth.login') }}">Sign In</a></p>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
{% endblock %}
|