Reset repo

This commit is contained in:
HugoNeveux 2020-04-20 17:48:22 +02:00
parent cd8467bfb7
commit b5e82d3c33
78 changed files with 1 additions and 52511 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
# ---> Python # ---> Python
# Byte-compiled / optimized / DLL files # Byte-compiled / optimized / DLL files
__pycache__/ __pycache__/

View File

@ -1,83 +0,0 @@
#!/bin/python
import mimetypes
from flask import Flask, request, session
from flask import url_for
from flask_admin import helpers as admin_helpers
from flask_babelex import Babel
from flask_security import Security, SQLAlchemyUserDatastore
from flask_uploads import patch_request_class
from PDMI.blueprints.admin import admin
from PDMI.blueprints.api import api, api_0_0_1
from PDMI.blueprints.front import front
from PDMI.blueprints.documentation import documentation
from PDMI.blueprints.external import external
from PDMI.models import db, Users, Roles
from PDMI.views import main_bp
# Config mimetype
mimetypes.add_type('text/css', '.css')
mimetypes.add_type('text/javascript', '.js')
server = Flask(__name__)
# Load config
server.config.from_object('PDMI.config')
# Create database
db.init_app(server)
with server.app_context():
db.create_all(app=server)
# Setup Flask-security
user_datastore = SQLAlchemyUserDatastore(db, Users, Roles)
security = Security(server, user_datastore)
patch_request_class(server, 16 * 1024 * 1024)
# Setup babel
babel = Babel(server)
@babel.localeselector
def get_locale():
if request.args.get('lang'):
session['lang'] = request.args.get('lang')
return session.get('lang', 'fr')
@security.context_processor
def security_context_processor():
return dict(
admin_base_template=admin.base_template,
admin_view=admin.index_view,
h=admin_helpers,
get_url=url_for
)
@server.context_processor
def utility_functions():
def print_in_console(message):
print(str(message))
return dict(mdebug=print_in_console)
# Register admin
admin.init_app(server)
# Register api
api.init_app(server)
api_0_0_1.init_app(server)
server.register_blueprint(front)
server.register_blueprint(documentation)
server.register_blueprint(external)
# Register main blueprint
server.register_blueprint(main_bp)
if __name__ == '__main__':
server.run()

View File

@ -1,147 +0,0 @@
import os
import wtforms as wtf
from flask import url_for, request
from flask_admin import Admin, AdminIndexView, expose
from flask_admin.contrib import sqla
from flask_admin.contrib import fileadmin
from flask_admin.menu import MenuLink
from flask_security import current_user
from werkzeug.exceptions import abort
from werkzeug.utils import redirect
from PDMI.models import db, Users, Modules, ModuleVersions, Roles
# from server.main import security
# Pour les fichiers
# def _imagename_uuid1_gen(obj, file_data):
# _, ext = os.path.splitext(file_data.filename)
# uid = uuid.uuid1()
# return secure_filename('{}{}'.format(uid, ext))
class BooleanField(wtf.BooleanField):
"""Boolean field without form-control class"""
def __call__(self, *args, **kwargs):
# Adding `readonly` property to `input` field
kwargs.update({'class': kwargs.get('class', '').replace("form-control", "")})
return super(BooleanField, self).__call__(*args, **kwargs)
class ConfigurableView(sqla.ModelView):
roles = []
details_modal = True
edit_modal = True
create_modal = True
def is_accessible(self):
if not current_user.is_active or not current_user.is_authenticated:
return False
if current_user.has_role("superadmin"):
return True
for role in self.roles:
if current_user.has_role(role):
return True
return False
def _handle_view(self, name, **kwargs):
"""
Override builtin _handle_view in order to redirect users when a view is not accessible.
"""
if not self.is_accessible():
if current_user.is_authenticated:
# permission denied
abort(403)
else:
# login
return redirect(url_for('security.login', next=request.url))
class SuperUserView(ConfigurableView):
roles = []
# Affichage de la table
column_editable_list = ['active', 'username', 'email', ]
column_searchable_list = ['active', 'username', 'email', ]
column_filters = ['active', 'username', 'email', 'roles', ]
column_exclude_list = ['password', ]
# Formulaire
form_excluded_columns = ['password', ]
form_columns = ['username', 'email', 'roles', 'active', ]
form_overrides = {
"active": BooleanField,
}
# Details
column_details_exclude_list = ['password', ]
class RolesView(ConfigurableView):
roles = []
class ModuleView(ConfigurableView):
inline_models = (
(
ModuleVersions,
{
'form_label': "Versions",
'form_columns': ('id', 'version',)
}
),
)
# Index view
class IndexView(AdminIndexView):
@expose('/')
def index(self):
return self.render('admin/index.html')
admin = Admin( # server,
index_view=IndexView(menu_icon_type='fa',
menu_icon_value='fa-home', ),
name='PDMI',
template_mode='bootstrap3',
category_icon_classes={
'Administration': 'fa fa-cogs',
},
endpoint='administration',
disconnect_route="security.logout",
connect_route="security.login",
favicon="favicon.ico"
)
admin.add_view(SuperUserView(
Users,
db.session,
menu_icon_type='fa',
menu_icon_value='fa-users',
name="Administrateurs",
category="Administration",
endpoint="admin.users"
))
admin.add_view(RolesView(
Roles,
db.session,
menu_icon_type='fa',
menu_icon_value='fa-users',
name="Roles",
category="Administration",
endpoint="admin.roles"
))
admin.add_view(ModuleView(
Modules,
db.session,
menu_icon_type="fa",
menu_icon_value="fa-gears",
name="Modules",
category="Modules",
endpoint="admin.modules"
))
admin.add_view(fileadmin.FileAdmin('modules',
'/files/', name='Module Files'))

View File

@ -1,28 +0,0 @@
from flask_restful import Api
from PDMI.blueprints.api.download import ApiIndex, ApiModuleList, ApiModuleVersions, ApiModuleGet
# Current version
api = Api(prefix="/api/current")
api.add_resource(ApiIndex, '/',
endpoint='api.download.index')
api.add_resource(ApiModuleList, "/modules/",
endpoint="api.download.modules.list")
api.add_resource(ApiModuleVersions, "/modules/<string:module>/",
endpoint="api.download.modules.versions")
api.add_resource(ApiModuleGet, "/modules/<string:module>/<string:version>/",
endpoint="api.download.modules.get")
# Version 0.0.1
api_0_0_1 = Api(prefix="/api/v/0.0.1")
api_0_0_1.add_resource(ApiIndex, '/',
endpoint='api.0_0_1.download.index')
api_0_0_1.add_resource(ApiModuleList, "/modules/",
endpoint="api.0_0_1.download.modules.list")
api_0_0_1.add_resource(ApiModuleVersions, "/modules/<string:module>/",
endpoint="api.0_0_1.download.modules.versions")
api_0_0_1.add_resource(ApiModuleGet, "/modules/<string:module>/<string:version>/",
endpoint="api.0_0_1.download.modules.get")

View File

@ -1,42 +0,0 @@
import os
import shutil
from flask import send_from_directory
from flask_restful import Resource, abort
from PDMI.models import Modules
class ApiIndex(Resource):
def get(self):
return {
"api version": "0.0.1"
}
class ApiModuleList(Resource):
def get(self):
modules = Modules.query.filter().all()
return {module.name: [version.version for version in module.versions] for module in modules}
class ApiModuleVersions(Resource):
def get(self, module):
module = Modules.query.filter_by(name=module).first_or_404()
return {"versions": [version.version for version in module.versions]}
class ApiModuleGet(Resource):
def get(self, module, version):
module = Modules.query.filter_by(name=module).first_or_404()
versions = [version.version for version in module.versions]
if version not in versions:
abort(404)
print(os.getcwd())
if not os.path.exists(os.path.join("PDMI", "modules", module.name, version + ".zip")):
shutil.make_archive(os.path.join("PDMI", "modules", module.name, version), 'zip',
os.path.join("PDMI", "modules", module.name, version))
return send_from_directory(
os.path.join("modules", module.name, ),
version + ".zip"
)

View File

@ -1,17 +0,0 @@
from flask import Blueprint, render_template, abort
documentation = Blueprint('documentation', __name__, template_folder="templates", url_prefix="/documentation")
@documentation.route("/")
def index():
return render_template("documentation/index.html")
@documentation.route("/create_module")
def create_module():
return render_template("documentation/create_module.html")
@documentation.route("/create_repository")
def create_repository():
return render_template("documentation/create_repository.html")

View File

@ -1,13 +0,0 @@
from flask import Blueprint, render_template, abort
external = Blueprint('external', __name__, template_folder="templates")
@external.route("/external/download")
def download():
return redirect("https://moriya.zapto.org/PDBA/bot-base", code=302)
@external.route("/external/download_server")
def download_server():
return redirect("https://moriya.zapto.org/PDBA/PDMI", code=302)

View File

@ -1,13 +0,0 @@
from flask import Blueprint, render_template, abort, send_from_directory
front = Blueprint('front', __name__, template_folder="templates")
@front.route('/favicon.ico')
def favicon():
return send_from_directory('static', 'favicon.ico', mimetype='image/vnd.microsoft.icon')
@front.route("/")
def index():
return render_template("front/index.html")

View File

@ -1,47 +0,0 @@
import os
# ======================================================================================================================
# ===================================================== general ========================================================
# ======================================================================================================================
# Secret key for decode cookies, generate new one for prod server, never share it
SECRET_KEY = "SECRET_KEY" # TODO
# Enable debug mode
DEBUG = True # TODO
# ======================================================================================================================
# =================================================== sqlalchemy =======================================================
# ======================================================================================================================
SQLALCHEMY_DATABASE_URI = "mysql+pymysql://"+os.environ["DATABASE_USER"]+":"+os.environ["DATABASE_PASSWORD"]+\
"@"+os.environ["DATABASE_HOST"]+":"+os.environ["DATABASE_PORT"]+"/"\
+os.environ["DATABASE_NAME"]
SQLALCHEMY_TRACK_MODIFICATIONS = False
# ======================================================================================================================
# ================================================= flask-security =====================================================
# ======================================================================================================================
# Protected urls
SECURITY_URL_PREFIX = "/admin"
# Pasword config
SECURITY_PASSWORD_HASH = "pbkdf2_sha512"
# Secret salt for password, generate new one for prod server, never share it
SECURITY_PASSWORD_SALT = "ATGUOHAELKiubahiughaerGOJAEGj" # TODO
# Urls for login/logout/register
SECURITY_LOGIN_URL = "/login/"
SECURITY_LOGOUT_URL = "/logout/"
SECURITY_REGISTER_URL = "/register/"
# Urls for page just after login/logout/register
SECURITY_POST_LOGIN_VIEW = "/admin/"
SECURITY_POST_LOGOUT_VIEW = "/admin/"
SECURITY_POST_REGISTER_VIEW = "/admin/"
# Features
SECURITY_REGISTERABLE = True
# todo: How can I activate that properly?
SECURITY_SEND_REGISTER_EMAIL = False # TODO
# ======================================================================================================================
# =================================================== flask-babel ======================================================
# ======================================================================================================================
BABEL_DEFAULT_LOCALE = "fr_FR"

View File

@ -1,54 +0,0 @@
import datetime
from flask_security import RoleMixin, UserMixin
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
roles_users = db.Table(
'roles_users',
db.Column('user_id', db.Integer(), db.ForeignKey('users.id', ondelete='CASCADE')),
db.Column('role_id', db.Integer(), db.ForeignKey('roles.id', ondelete='CASCADE'))
)
class Roles(db.Model, RoleMixin):
__tablename__ = "roles"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), unique=True)
description = db.Column(db.String(255))
def __str__(self):
return self.name
class Modules(db.Model):
__tablename__ = "modules"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(100))
versions = db.relationship('ModuleVersions', backref='modules', lazy=True)
class ModuleVersions(db.Model):
__tablename__ = "moduleversions"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
version = db.Column(db.String(10))
module_id = db.Column(db.Integer, db.ForeignKey('modules.id'), nullable=False)
class Users(db.Model, UserMixin):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True)
date_created = db.Column(db.DateTime, default=datetime.datetime.utcnow)
username = db.Column(db.String(100))
email = db.Column(db.String(100), unique=True)
password = db.Column(db.String(200))
active = db.Column(db.Boolean)
roles = db.relationship('Roles', secondary=roles_users,
backref=db.backref('users', lazy='dynamic'))
def __repr__(self):
return str(self.username)
def __str__(self):
return str(self.username)

View File

@ -1,19 +0,0 @@
from modules.base import BaseClass
class MainClass(BaseClass):
name = "Panic"
help_active = True
help = {
"description": "Dans quel état est Nikola Tesla",
"commands": {
"`{prefix}{command}`": "Donne l'état actuel de Nikola Tesla",
}
}
command_text = "panic"
async def command(self, message, args, kwargs):
temperature = 0
with open("/sys/class/thermal/thermal_zone0/temp") as f:
temperature = int(f.read().rstrip("\n")) / 1000
await message.channel.send("Nikola est à {temperature}°C".format(temperature=temperature))

View File

@ -1,13 +0,0 @@
{
"version": "0.1.0",
"dependencies": {
"base": {
"min": "0.1.0",
"max": "0.1.0"
}
},
"bot_version": {
"min": "0.1.0",
"max": "0.1.0"
}
}

View File

@ -1,19 +0,0 @@
from modules.base import BaseClass
class MainClass(BaseClass):
name = "Panic"
help_active = True
help = {
"description": "Dans quel état est Nikola TeslaTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOTOOTOTOTOTOTOTOTOTOT",
"commands": {
"`{prefix}{command}`": "Donne l'état actuel de Nikola Tesla",
}
}
command_text = "panic"
async def command(self, message, args, kwargs):
temperature = 0
with open("/sys/class/thermal/thermal_zone0/temp") as f:
temperature = int(f.read().rstrip("\n")) / 1000
await message.channel.send("Nikola est à {temperature}°C".format(temperature=temperature))

View File

@ -1,10 +0,0 @@
{
"name": "panic",
"version": "0.0.2",
"requirement": {
"base": {
"min": "0.0.2",
"max": "0.0.2"
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,331 +0,0 @@
/*!
* Bootstrap Reboot v4.3.1 (https://getbootstrap.com/)
* Copyright 2011-2019 The Bootstrap Authors
* Copyright 2011-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
font-family: sans-serif;
line-height: 1.15;
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
display: block;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
background-color: #fff;
}
[tabindex="-1"]:focus {
outline: 0 !important;
}
hr {
box-sizing: content-box;
height: 0;
overflow: visible;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: 0.5rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-original-title] {
text-decoration: underline;
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
border-bottom: 0;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: .5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 80%;
}
sub,
sup {
position: relative;
font-size: 75%;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -.25em;
}
sup {
top: -.5em;
}
a {
color: #007bff;
text-decoration: none;
background-color: transparent;
}
a:hover {
color: #0056b3;
text-decoration: underline;
}
a:not([href]):not([tabindex]) {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):focus {
outline: 0;
}
pre,
code,
kbd,
samp {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 1em;
}
pre {
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
}
figure {
margin: 0 0 1rem;
}
img {
vertical-align: middle;
border-style: none;
}
svg {
overflow: hidden;
vertical-align: middle;
}
table {
border-collapse: collapse;
}
caption {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
color: #6c757d;
text-align: left;
caption-side: bottom;
}
th {
text-align: inherit;
}
label {
display: inline-block;
margin-bottom: 0.5rem;
}
button {
border-radius: 0;
}
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
select {
word-wrap: normal;
}
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
button:not(:disabled),
[type="button"]:not(:disabled),
[type="reset"]:not(:disabled),
[type="submit"]:not(:disabled) {
cursor: pointer;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
padding: 0;
border-style: none;
}
input[type="radio"],
input[type="checkbox"] {
box-sizing: border-box;
padding: 0;
}
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
-webkit-appearance: listbox;
}
textarea {
overflow: auto;
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
display: block;
width: 100%;
max-width: 100%;
padding: 0;
margin-bottom: .5rem;
font-size: 1.5rem;
line-height: inherit;
color: inherit;
white-space: normal;
}
progress {
vertical-align: baseline;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
outline-offset: -2px;
-webkit-appearance: none;
}
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
summary {
display: list-item;
cursor: pointer;
}
template {
display: none;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,331 +0,0 @@
/*!
* Bootstrap Reboot v4.3.1 (https://getbootstrap.com/)
* Copyright 2011-2019 The Bootstrap Authors
* Copyright 2011-2019 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
font-family: sans-serif;
line-height: 1.15;
-webkit-text-size-adjust: 100%;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
display: block;
}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 1rem;
font-weight: 400;
line-height: 1.5;
color: #212529;
text-align: left;
background-color: #fff;
}
[tabindex="-1"]:focus {
outline: 0 !important;
}
hr {
box-sizing: content-box;
height: 0;
overflow: visible;
}
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: 0.5rem;
}
p {
margin-top: 0;
margin-bottom: 1rem;
}
abbr[title],
abbr[data-original-title] {
text-decoration: underline;
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
cursor: help;
border-bottom: 0;
-webkit-text-decoration-skip-ink: none;
text-decoration-skip-ink: none;
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: 700;
}
dd {
margin-bottom: .5rem;
margin-left: 0;
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: bolder;
}
small {
font-size: 80%;
}
sub,
sup {
position: relative;
font-size: 75%;
line-height: 0;
vertical-align: baseline;
}
sub {
bottom: -.25em;
}
sup {
top: -.5em;
}
a {
color: #007bff;
text-decoration: none;
background-color: transparent;
}
a:hover {
color: #0056b3;
text-decoration: underline;
}
a:not([href]):not([tabindex]) {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {
color: inherit;
text-decoration: none;
}
a:not([href]):not([tabindex]):focus {
outline: 0;
}
pre,
code,
kbd,
samp {
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 1em;
}
pre {
margin-top: 0;
margin-bottom: 1rem;
overflow: auto;
}
figure {
margin: 0 0 1rem;
}
img {
vertical-align: middle;
border-style: none;
}
svg {
overflow: hidden;
vertical-align: middle;
}
table {
border-collapse: collapse;
}
caption {
padding-top: 0.75rem;
padding-bottom: 0.75rem;
color: #6c757d;
text-align: left;
caption-side: bottom;
}
th {
text-align: inherit;
}
label {
display: inline-block;
margin-bottom: 0.5rem;
}
button {
border-radius: 0;
}
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
input,
button,
select,
optgroup,
textarea {
margin: 0;
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
button,
input {
overflow: visible;
}
button,
select {
text-transform: none;
}
select {
word-wrap: normal;
}
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
button:not(:disabled),
[type="button"]:not(:disabled),
[type="reset"]:not(:disabled),
[type="submit"]:not(:disabled) {
cursor: pointer;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
padding: 0;
border-style: none;
}
input[type="radio"],
input[type="checkbox"] {
box-sizing: border-box;
padding: 0;
}
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
-webkit-appearance: listbox;
}
textarea {
overflow: auto;
resize: vertical;
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
display: block;
width: 100%;
max-width: 100%;
padding: 0;
margin-bottom: .5rem;
font-size: 1.5rem;
line-height: inherit;
color: inherit;
white-space: normal;
}
progress {
vertical-align: baseline;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
outline-offset: -2px;
-webkit-appearance: none;
}
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-file-upload-button {
font: inherit;
-webkit-appearance: button;
}
output {
display: inline-block;
}
summary {
display: list-item;
cursor: pointer;
}
template {
display: none;
}
[hidden] {
display: none !important;
}
/*# sourceMappingURL=bootstrap-reboot.css.map */

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,49 +0,0 @@
{% extends 'admin/master.html' %}
{% block body %}
{{ super() }}
{% if current_user.is_authenticated %}
<!-- Content Header (Page header) -->
<section class="content-header">
<h1>
Tableau de bord
<small>Panneau de contrôle</small>
</h1>
<ol class="breadcrumb">
<li><a href="#"><i class="fa fa-dashboard"></i> Tableau de bord</a></li>
<li class="active">Panneau de contrôle</li>
</ol>
</section>
<section class="content">
{# todo: Fill index page #}
</section>
<!-- /.content -->
{% else %}
<section class="content" style="color: white;text-align: center;height:100%;width: 50%;
margin: 0 auto;">
<div class="col-sm-12">
<h1>LBI - PiPy</h1>
<p class="lead">
Connection
</p>
<p>
Pour accéder à l'interface d'administration veuillez utiliser vos identifiants.
</p>
<p>
<a class="btn btn-primary" href="{{ url_for('security.login') }}">Connection</a>
</p>
<br>
<p>
<a class="btn btn-primary" href="/"><i class="glyphicon glyphicon-chevron-left"></i> Retour</a>
</p>
</div>
</section>
<br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>
{% endif %}
{% endblock body %}

View File

@ -1 +0,0 @@
{% extends admin_base_template %}

View File

@ -1,20 +0,0 @@
<!doctype html>
<html lang="fr">
<head>
<title>{% block title %}PDMI - Documentation{% endblock %}</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="PDMI - Python Discord Module Index">
<meta name="author" content="Louis Chauvet">
<!-- Favicon.ico -->
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
<link href="{{ url_for('static', filename='documentation/vendor/bootstrap-4.3.1/css/bootstrap.css') }}" rel="stylesheet">
</head>
<body>
{% include "front/base/navbar.html" %}
{% block body %}
{% endblock %}
</body>
</html>

View File

@ -1,5 +0,0 @@
{% extends 'documentation/base/base.html' %}
{% block body %}
create_module
{% endblock %}

View File

@ -1,5 +0,0 @@
{% extends 'documentation/base/base.html' %}
{% block body %}
create_repository
{% endblock %}

View File

@ -1,5 +0,0 @@
{% extends 'documentation/base/base.html' %}
{% block body %}
index
{% endblock %}

View File

@ -1,20 +0,0 @@
<!doctype html>
<html lang="fr">
<head>
<title>{% block title %}PDMI - Python Discord Module Index{% endblock %}</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="PDMI - Python Discord Module Index">
<meta name="author" content="Louis Chauvet">
<!-- Favicon.ico -->
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
<link href="{{ url_for('static', filename='front/vendor/bootstrap-4.3.1/css/bootstrap.css') }}" rel="stylesheet">
</head>
<body>
{% include "front/base/navbar.html" %}
{% block body %}
{% endblock %}
</body>
</html>

View File

@ -1,31 +0,0 @@
<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
<a class="navbar-brand" href="#">P.D.M.I</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="{{ url_for('front.index') }}">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('documentation.index') }}">Documentation</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="dropdown01" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Download</a>
<div class="dropdown-menu" aria-labelledby="dropdown01">
<a class="dropdown-item" href="{{ url_for('external.download') }}">Download bot</a>
<a class="dropdown-item" href="{{ url_for('external.download_server') }}">Download server</a>
</div>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for('admin.index') }}">Gestion des modules</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>

View File

@ -1,69 +0,0 @@
{% extends 'front/base/base.html' %}
{% block body %}
<main role="main">
<!-- Main jumbotron for a primary marketing message or call to action -->
<div class="jumbotron">
<div class="container">
<h1 class="display-3">PDMI - Python Discord Module Index</h1>
<p>
PDMI is a part of PDBA project. PDBA is a basic discord bot which integrate possibility to install
modules.
PDMI is the website where most of modules are uploaded. If you want to create your own module you can
check
<a href="{{ url_for('documentation.create_module') }}">documentation</a>. You can also create your own
<a href="{{ url_for('documentation.create_repository') }}">repository</a>.
</p>
<p><a class="btn btn-primary btn-lg" href="{{ url_for('documentation.index') }}" role="button">Learn more
&raquo;</a></p>
</div>
</div>
{#
<div class="container">
<!-- Example row of columns -->
<div class="row">
<div class="col-md-4">
<h2>Heading</h2>
<p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor
mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna
mollis euismod. Donec sed odio dui. </p>
<p><a class="btn btn-secondary" href="#" role="button">View details &raquo;</a></p>
</div>
<div class="col-md-4">
<h2>Heading</h2>
<p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor
mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna
mollis euismod. Donec sed odio dui. </p>
<p><a class="btn btn-secondary" href="#" role="button">View details &raquo;</a></p>
</div>
<div class="col-md-4">
<h2>Heading</h2>
<p>Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula
porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh,
ut fermentum massa justo sit amet risus.</p>
<p><a class="btn btn-secondary" href="#" role="button">View details &raquo;</a></p>
</div>
</div>
<hr>
</div> <!-- /container -->#}
</main>
<footer class="container">
<p>&copy; Louis Chauvet 2019</p>
</footer>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous"></script>
<script>window.jQuery || document.write('<script src="/docs/4.3/assets/js/vendor/jquery-slim.min.js"><\/script>')
</script>
<script src="/docs/4.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-xrRywqdh3PHs8keKZN+8zzc5TX0GRTLCcmivcbNJWm2rs5C8PRhcEn3czEjhAO9o"
crossorigin="anonymous"></script>
{% endblock %}

View File

@ -1,16 +0,0 @@
<!doctype html>
<html lang="fr">
<head>
<title>PDMI - Python Discord Module Index</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="PDMI - Python Discord Module Index">
<meta name="author" content="Louis Chauvet">
<!-- Favicon.ico -->
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
</head>
<body>
<a href="{{ url_for("admin.index") }}">Connection à la gestion des modules</a><br/>
</body>
</html>

View File

@ -1,27 +0,0 @@
{% macro render_field_with_errors(field) %}
<div class="form-group">
{{ field.label }} {{ field(class_='form-control', **kwargs)|safe }}
{% if field.errors %}
<ul>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endmacro %}
{% macro render_field(field) %}
<p>{{ field(class_='form-control', **kwargs)|safe }}</p>
{% endmacro %}
{% macro render_checkbox_field(field) -%}
<div class="form-group">
<div class="checkbox">
<label>
{{ field(type='checkbox', **kwargs) }} {{ field.label }}
</label>
</div>
</div>
{%- endmacro %}

View File

@ -1,19 +0,0 @@
{% if security.registerable or security.recoverable or security.confirmable %}
<h2>Menu</h2>
<ul>
<li><a href="
{{ url_for_security('login') }}{% if 'next' in request.args %}?next={{ request.args.next|urlencode }}{% endif %}">Login</a>
</li>
{% if security.registerable %}
<li><a href="
{{ url_for_security('register') }}{% if 'next' in request.args %}?next={{ request.args.next|urlencode }}{% endif %}">Register</a><br/>
</li>
{% endif %}
{% if security.recoverable %}
<li><a href="{{ url_for_security('forgot_password') }}">Forgot password</a><br/></li>
{% endif %}
{% if security.confirmable %}
<li><a href="{{ url_for_security('send_confirmation') }}">Confirm account</a></li>
{% endif %}
</ul>
{% endif %}

View File

@ -1,9 +0,0 @@
{%- with messages = get_flashed_messages(with_categories=true) -%}
{% if messages %}
<ul class="flashes">
{% for category, message in messages %}
<li class="{{ category }}">{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{%- endwith %}

View File

@ -1,24 +0,0 @@
{% extends 'admin/master.html' %}
{% from "security/_macros.html" import render_field, render_field_with_errors, render_checkbox_field %}
{% include "security/_messages.html" %}
{% block body %}
{{ super() }}
<br><br><br><br><br>
<section class="content">
<div class="col-sm-8 col-sm-offset-2">
<div class="well">
<h1>Login</h1>
<form action="{{ url_for_security('login') }}" method="POST" name="login_user_form">
{{ login_user_form.hidden_tag() }}
{{ render_field_with_errors(login_user_form.email) }}
{{ render_field_with_errors(login_user_form.password) }}
{{ render_checkbox_field(login_user_form.remember) }}
{{ render_field(login_user_form.next) }}
{{ render_field(login_user_form.submit, class="btn btn-primary") }}
</form>
</div>
</div>
</section>
<br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br>
{% endblock body %}

View File

@ -1,28 +0,0 @@
{% extends 'admin/master.html' %}
{% from "security/_macros.html" import render_field_with_errors, render_field %}
{% include "security/_messages.html" %}
{% block body %}
{{ super() }}
<br><br><br><br>
<div class="row-fluid">
<div class="col-sm-8 col-sm-offset-2">
<br>
<div class="well">
<h1>Register</h1>
<form action="{{ url_for_security('register') }}" method="POST" name="register_user_form">
{{ register_user_form.hidden_tag() }}
{{ render_field_with_errors(register_user_form.email) }}
{{ render_field_with_errors(register_user_form.password) }}
{% if register_user_form.password_confirm %}
{{ render_field_with_errors(register_user_form.password_confirm) }}
{% endif %}
{{ render_field(register_user_form.submit, class="btn btn-primary") }}
</form>
<p>Already signed up? Please <a href="{{ url_for('security.login') }}">log in</a>.</p>
</div>
</div>
</div>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
{% endblock body %}

View File

@ -1,10 +0,0 @@
import os
from flask import render_template, Blueprint, send_from_directory
main_bp = Blueprint('', __name__)
@main_bp.route('/favicon.ico')
def favicon():
return send_from_directory('static', 'favicon.ico', mimetype='image/vnd.microsoft.icon')

32
Pipfile
View File

@ -1,32 +0,0 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
flask-admin = {git = "https://github.com/Fomys/flask-admin"}
flask = "*"
flask-babelex = "*"
flask-security = "*"
flask-migrate = "*"
flask-script = "*"
flask-uploads = "*"
sqlalchemy = "*"
flask-sqlalchemy = "*"
flask-restful = "*"
gunicorn = "*"
aiohttp = "*"
pymysql = "*"
mysqlclient = "*"
[dev-packages]
[requires]
python_version = "3.7"

417
conf.sh
View File

@ -1,417 +0,0 @@
#!/bin/sh
SCRIPT_NAME=$0
#################
# Configuration #
#################
# List of all env variable
declare -A DATABASE_VAR_DESCRIPTION
DATABASE_VAR_DESCRIPTION["DATABASE_HOST"]="Set database host"
DATABASE_VAR_DESCRIPTION["DATABASE_PORT"]="Set database port"
DATABASE_VAR_DESCRIPTION["DATABASE_USER"]="Set database user"
DATABASE_VAR_DESCRIPTION["DATABASE_PASSWORD"]="Set database password, never share your .env file, your password is stored in clear"
DATABASE_VAR_DESCRIPTION["DATABASE_NAME"]="Set database name"
DATABASE_VARS="${!DATABASE_VAR_DESCRIPTION[@]}"
declare -A CONFIG_CATEGORIES_DESCRIPTION
CONFIG_CATEGORIES_DESCRIPTION["DATABASE"]="Set database related config vars"
CONFIG_CATEGORIES=(DATABASE)
CONFIG_VARS="$DATABASE_VARS"
################
# USEFULL VARS #
################
# Usefull vars for using dialog, kdialog and xdialog
: ${DIALOG_OK=0}
: ${DIALOG_CANCEL=1}
: ${DIALOG_HELP=2}
: ${DIALOG_EXTRA=3}
: ${DIALOG_ITEM_HELP=4}
: ${DIALOG_ESC=255}
# Colors
: ${BLACK='\033[0:30m'}
: ${RED='\033[0;31m'}
: ${GREEN='\033[0;32m'}
: ${ORANGE='\033[0;33m'}
: ${BLUE='\033[0;34m'}
: ${PURPLE='\033[0;35m'}
: ${CYAN='\033[0;36m'}
: ${LIGHT_GRAY='\033[0;37m'}
: ${DARK_GRAY='\033[1;30m'}
: ${LIGHT_RED='\033[1;31m'}
: ${LIGHT_GREEN='\033[1;32m'}
: ${YELLOW='\033[1;33m'}
: ${LIGHT_BLUE='\033[1;34m'}
: ${LIGHT_PURPLE='\033[1;35m'}
: ${LIGHT_CYAN='\033[1;36m'}
: ${WHITE='\033[1;37m'}
: ${NC='\033[0m'}
##########################
# Rewrite beautiful echo #
##########################
einfo () {
# einfo "comment"
echo -e " ${GREEN}*${NC} ${@:1}${NC}"
}
ewarn () {
# ewarn "comment"
echo -e " ${YELLOW}*${NC} ${@:1}${NC}"
}
eerror () {
# eerror "comment"
echo -e " ${RED}*${LIGHT_RED} ${@:1}${NC}"
}
die () {
# die exit_code "comment"
echo
eerror $2
exit $1
}
eend () {
# eend exit_status "comment"
einfo $2
exit $1
}
show_help () {
# show_help
echo "Usage : PDMI-configure [OPTIONS...]"
echo
echo " -h, --help Print this help menu"
echo " --xdialog Use xdialog instead of dialog"
}
####################
# Useful functions #
####################
###################
# Parse arguments #
###################
SHORT=h:
LONG=xdialog,help,easter-egg:
OPTS=$(getopt --options ${SHORT} --long ${LONG} --name "$0" -- "$@")
# Problem when parsing args
if [[ $? != 0 ]] ; then echo "Failed to parse options...exiting." >&2 ; exit 1 ; fi
eval set -- "${OPTS}"
DIALOG=dialog
while true ; do
case "$1" in
--xdialog )
which Xdialog && : || die 1 "Xdialog not found"
DIALOG=Xdialog
shift
;;
--easter-egg)
die 0 "Suwako, je t'ai vu décortiquer le fichier"
;;
-h | --help )
show_help
end
shift
;;
-- )
shift
break
;;
*)
echo "Internal error!"
exit 1
;;
esac
done
set_env_var () {
load_config
exec 3>&1
local value=$(${DIALOG} \
--backtitle "Configuration" \
--title $1 \
--inputbox "Veuillez insérez la nouvelle valeur de la variable ${1}:" \
0 0 \
${!1} \
2>&1 1>&3)
local exit_status=$?
exec 3>&-
export ${1}=$value
save_config
}
set_env_vars_cat () {
clear
CATEGORY=$1
CATEGORY_VARS_NAME=${1}_VARS
CAT=${!CATEGORY_VARS_NAME}
CATEGORY_LIST=($CAT)
local OPTIONS=""
local COUNT=${#CATEGORY_LIST[@]}
for I in `seq 1 ${COUNT}`;
do
OPTIONS="$OPTIONS "${I}" "${CATEGORY_LIST[$(($I-1))]}""
done
echo $OPTIONS
exec 3>&1
selection=$(${DIALOG} \
--backtitle "PDMI - Configuration" \
--title "Set $CATEGORY vars" \
--help-button \
--menu "Choose an option" \
-1 -1 0 \
${OPTIONS} \
2>&1 1>&3)
exit_status=$?
exec 3>&-
case ${exit_status} in
${DIALOG_CANCEL})
return
;;
${DIALOG_HELP})
;;
${DIALOG_ESC})
return
;;
esac
set_env_var ${CATEGORY_LIST[$(($selection-1))]}
}
set_env_vars () {
local OPTIONS=""
local COUNT=`echo "$CONFIG_CATEGORIES" | wc -w`
for I in `seq 1 ${COUNT}`;
do
OPTIONS="$OPTIONS "${I}" "${CONFIG_CATEGORIES[$(($I-1))]}""
done
exec 3>&1
selection=$(${DIALOG} \
--backtitle "PDMI - Configuration" \
--title "Set configuration vars" \
--help-button \
--menu "Choose an option" \
-1 -1 0 \
${OPTIONS} \
2>&1 1>&3)
exit_status=$?
exec 3>&-
case ${exit_status} in
${DIALOG_CANCEL})
return
;;
${DIALOG_HELP})
local HELP=""
for NAME in ${!CONFIG_CATEGORIES_DESCRIPTION[@]}; do
HELP="$HELP\n${NAME} - ${CONFIG_CATEGORIES_DESCRIPTION[${NAME}]}"
done
echo ${HELP}
${DIALOG} \
--backtitle "PDMI - Set configuration vars" \
--title "Set configuration vars - Help" \
--msgbox "$HELP" \
-1 -1
;;
${DIALOG_ESC})
return
;;
esac
set_env_vars_cat $CONFIG_CATEGORIES
}
load_config () {
export $(cat .env | xargs)
}
save_config () {
rm .env
for VAR in ${CONFIG_VARS}
do
if [[ -z ${!VAR} ]]; then
export ${VAR}=${VAR}
fi
echo ${VAR}=${!VAR} >> .env
done
}
bdd_config () {
exec 3>&1
local selection=$(${DIALOG} \
--backtitle "Base de donnée" \
--menu "Que souhaitez vous faire?" \
0 0 0 \
"1" "manage db init" \
"2" "manage db migrate" \
"3" "manage db upgrade" \
2>&1 1>&3)
local exit_status=$?
exec 3>&-
source .env
case ${selection} in
1)
pipenv run python manage.py db init;;
2)
pipenv run python manage.py db migrate;;
3)
pipenv run python manage.py db upgrade;;
esac
}
add_super_admin () {
exec 3>&1
local utilisateur=$(${DIALOG} \
--backtitle "Utilitaires" \
--title "Administrateurs" \
--inputbox "Entrez le mail de l'utilisateur que vous voulez passer en superadministrateur" \
0 0 \
"" \
2>&1 1>&3)
local exit_status=$?
exec 3>&-
source .env
pipenv run python manage.py set_superadmin -m "${utilisateur}"
exit
}
utilitaires () {
exec 3>&1
selection=$(${DIALOG} \
--backtitle "Utilitaires" \
--menu "Que voulez vous faire?" \
0 0 0 \
"1" "Ajouter un superadministrateur" \
"2" "Installation de pipenv" \
2>&1 1>&3)
exit_status=$?
exec 3>&-
case ${selection} in
1)
add_super_admin;;
2)
pipenv install;;
esac
}
check_config_file () {
clear
export $(cat .env | xargs)
rm .env
echo ${CONFIG_VARS}
for VAR in ${CONFIG_VARS}
do
echo ${VAR}=${!VAR}
if [[ -z ${!VAR} ]]; then
export ${VAR}=${VAR}
fi
echo ${VAR}=${!VAR} >> .env
done
}
initialisation () {
:
}
start () {
pipenv run gunicorn wsgy -b 0.0.0.0:8000
}
configuration () {
exec 3>&1
selection=$(${DIALOG} \
--backtitle "PDMI - Configuration" \
--title "Configuration" \
--help-button \
--menu "Choose an option" \
-1 -1 0 \
"1" "Check config file" \
"2" "Set configuration" \
"-" "" \
"3" "Exit" \
2>&1 1>&3)
exit_status=$?
exec 3>&-
case ${exit_status} in
${DIALOG_OK})
;;
${DIALOG_CANCEL})
return
;;
${DIALOG_HELP})
${DIALOG} \
--backtitle "PDMI - Configuration" \
--title "Configuration - Help" \
--msgbox "Check config file - Check config file integrity
Set configuration - Set configuration" \
-1 -1
;;
${DIALOG_ESC})
return
;;
esac
case ${selection} in
1)
check_config_file
;;
2)
set_env_vars
;;
3)
break
;;
esac
}
# Main loop
while true; do
exec 3>&1
selection=$(${DIALOG} \
--backtitle "PDMI - Configuration" \
--title "Configuration" \
--help-button \
--menu "Choose an option" \
-1 -1 0 \
"1" "Initialisation" \
"2" "Configuration" \
"3" "Start" \
"-" "-" \
"4" "Quit" \
2>&1 1>&3)
exit_status=$?
exec 3>&-
case ${exit_status} in
${DIALOG_OK})
;;
${DIALOG_CANCEL})
eend 0 "End."
;;
${DIALOG_HELP})
${DIALOG} \
--backtitle "PDMI - Configuration" \
--title "Configuration - Help" \
--msgbox "Initialisation - \n\nConfiguration - Configure usefull parameters, such as port, database uri, ..." \
-1 -1
;;
${DIALOG_ESC})
eend 0 "End."
;;
esac
case ${selection} in
1)
initialisation;;
2)
configuration;;
3)
start;;
4)
exit;;
esac
done

View File

@ -1,51 +0,0 @@
from flask import url_for
from flask_migrate import Migrate, MigrateCommand
from flask_script import Manager
from PDMI import server, db, Roles, Users
server.config.from_object('PDMI.config')
migrate = Migrate(server, db)
manager = Manager(server)
manager.add_command('db', MigrateCommand)
@manager.option('-m', '--mail', help="Mail de l'utilisateur à mettre en admin")
def set_superadmin(mail):
roles = Roles.query.filter(Roles.name == "superadmin").all()
if len(roles) == 0:
superAdminRole = Roles(name="superadmin", description="Role pour les super administrateurs")
db.session.add(superAdminRole)
db.session.commit()
role = Roles.query.filter(Roles.name == "superadmin").first()
users = Users.query.filter(Users.email == mail).all()
if len(users) == 0:
print("Aucun compte avec le mail {mail} existe, annulation".format(mail=mail))
return
user = Users.query.filter(Users.email == mail).first()
user.roles.append(role)
db.session.commit()
print("Role ajouté")
@manager.command
def list_routes():
import urllib.parse
output = []
for rule in server.url_map.iter_rules():
options = {}
for arg in rule.arguments:
if arg == "id":
options[arg] = "0"
else:
options[arg] = f"[{arg}]"
methods = ",".join(rule.methods)
url = url_for(rule.endpoint, **options)
line = urllib.parse.unquote("{:50s} {:20s} {}".format(rule.endpoint, methods, url))
output.append(line)
for line in sorted(output):
print(line)
if __name__ == '__main__':
manager.run()

View File

@ -1,4 +0,0 @@
from PDMI import server as application
if __name__ == "__main__":
application.run()