mirror of
https://github.com/Derpy-Leggies/OnlyLegs.git
synced 2025-02-13 17:00:05 +00:00
Yeet old runner script as it was useless
Clean up code and styling
This commit is contained in:
parent
8a4fe891ef
commit
9821db72c6
115
onlylegs/app.py
115
onlylegs/app.py
|
@ -1,67 +1,55 @@
|
||||||
"""
|
"""
|
||||||
Onlylegs Gallery
|
Onlylegs Gallery
|
||||||
This is the main app file, it loads all the other files and sets up the app
|
This is the main app file, checks on app stability and runs all da shit
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from flask_assets import Bundle
|
from flask_assets import Bundle
|
||||||
from flask_migrate import init as migrate_init
|
from flask_migrate import init as migrate_init
|
||||||
|
from flask import Flask, render_template, abort, request
|
||||||
from flask import Flask, render_template, abort
|
|
||||||
from werkzeug.exceptions import HTTPException
|
from werkzeug.exceptions import HTTPException
|
||||||
from werkzeug.security import generate_password_hash
|
|
||||||
|
|
||||||
|
from onlylegs.utils import startup
|
||||||
from onlylegs.extensions import db, migrate, login_manager, assets, compress, cache
|
from onlylegs.extensions import db, migrate, login_manager, assets, compress, cache
|
||||||
from onlylegs.config import INSTANCE_DIR, MIGRATIONS_DIR
|
from onlylegs.config import INSTANCE_DIR, MIGRATIONS_DIR, APPLICATION_ROOT
|
||||||
from onlylegs.models import Users
|
from onlylegs.models import Users
|
||||||
from onlylegs.views import (
|
|
||||||
index as view_index,
|
from onlylegs.views.index import blueprint as view_index
|
||||||
image as view_image,
|
from onlylegs.views.image import blueprint as view_image
|
||||||
group as view_group,
|
from onlylegs.views.group import blueprint as view_group
|
||||||
settings as view_settings,
|
from onlylegs.views.settings import blueprint as view_settings
|
||||||
profile as view_profile,
|
from onlylegs.views.profile import blueprint as view_profile
|
||||||
|
from onlylegs.api import blueprint as api
|
||||||
|
from onlylegs.auth import blueprint as view_auth
|
||||||
|
from onlylegs.filters import blueprint as filters
|
||||||
|
|
||||||
|
|
||||||
|
logging.getLogger("werkzeug").disabled = True
|
||||||
|
logging.basicConfig(
|
||||||
|
filename=os.path.join(APPLICATION_ROOT, "only.log"),
|
||||||
|
level=logging.INFO,
|
||||||
|
datefmt="%Y-%m-%d %H:%M:%S",
|
||||||
|
format="%(asctime)s %(levelname)s %(name)s %(threadName)s : %(message)s",
|
||||||
|
encoding="utf-8",
|
||||||
)
|
)
|
||||||
from onlylegs import api
|
|
||||||
from onlylegs import auth as view_auth
|
|
||||||
from onlylegs import filters
|
|
||||||
|
|
||||||
app = Flask(__name__, instance_path=INSTANCE_DIR)
|
app = Flask(__name__, instance_path=INSTANCE_DIR)
|
||||||
app.config.from_pyfile("config.py")
|
app.config.from_pyfile("config.py")
|
||||||
|
|
||||||
# DATABASE
|
|
||||||
db.init_app(app)
|
db.init_app(app)
|
||||||
migrate.init_app(app, db, directory=MIGRATIONS_DIR)
|
migrate.init_app(app, db, directory=MIGRATIONS_DIR)
|
||||||
|
|
||||||
# If database file doesn't exist, create it
|
# App Sanity Checks
|
||||||
|
startup.check_dirs()
|
||||||
|
startup.check_env()
|
||||||
|
startup.check_conf()
|
||||||
|
|
||||||
if not os.path.exists(os.path.join(INSTANCE_DIR, "gallery.sqlite3")):
|
if not os.path.exists(os.path.join(INSTANCE_DIR, "gallery.sqlite3")):
|
||||||
print("Creating database")
|
startup.make_admin_user(app)
|
||||||
with app.app_context():
|
migrate_init(directory=MIGRATIONS_DIR)
|
||||||
db.create_all()
|
|
||||||
|
|
||||||
register_user = Users(
|
|
||||||
username=app.config["ADMIN_CONF"]["username"],
|
|
||||||
email=app.config["ADMIN_CONF"]["email"],
|
|
||||||
password=generate_password_hash("changeme!", method="sha256"),
|
|
||||||
)
|
|
||||||
db.session.add(register_user)
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
print(
|
|
||||||
"""
|
|
||||||
####################################################
|
|
||||||
# DEFAULT ADMIN USER GENERATED WITH GIVEN USERNAME #
|
|
||||||
# THE DEFAULT PASSWORD "changeme!" HAS BEEN USED, #
|
|
||||||
# PLEASE UPDATE IT IN THE SETTINGS! #
|
|
||||||
####################################################
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
# Check if migrations directory exists, if not create it
|
|
||||||
with app.app_context():
|
|
||||||
if not os.path.exists(MIGRATIONS_DIR):
|
|
||||||
print("Creating migrations directory")
|
|
||||||
migrate_init(directory=MIGRATIONS_DIR)
|
|
||||||
|
|
||||||
# LOGIN MANAGER
|
# LOGIN MANAGER
|
||||||
# can also set session_protection to "strong"
|
# can also set session_protection to "strong"
|
||||||
|
@ -90,40 +78,41 @@ def error_page(err):
|
||||||
"""
|
"""
|
||||||
if not isinstance(err, HTTPException):
|
if not isinstance(err, HTTPException):
|
||||||
abort(500)
|
abort(500)
|
||||||
return (
|
|
||||||
render_template("error.html", error=err.code, msg=err.description),
|
if request.method == "GET":
|
||||||
err.code,
|
return (
|
||||||
)
|
render_template("error.html", error=err.code, msg=err.description),
|
||||||
|
err.code,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return str(err.code) + ": " + err.description, err.code
|
||||||
|
|
||||||
|
|
||||||
# ASSETS
|
# ASSETS
|
||||||
assets.init_app(app)
|
assets.init_app(app)
|
||||||
|
|
||||||
scripts = Bundle(
|
page_scripts = Bundle(
|
||||||
"js/*.js", output="gen/js.js", depends="js/*.js"
|
"js/*.js", filters="jsmin", output="gen/main.js", depends="js/*.js"
|
||||||
) # filter jsmin is broken :c
|
)
|
||||||
styles = Bundle(
|
page_styling = Bundle(
|
||||||
"sass/style.sass",
|
"sass/style.sass",
|
||||||
filters="libsass, cssmin",
|
filters="libsass, cssmin",
|
||||||
output="gen/styles.css",
|
output="gen/styles.css",
|
||||||
depends="sass/**/*.sass",
|
depends="sass/**/*.sass",
|
||||||
)
|
)
|
||||||
|
|
||||||
assets.register("scripts", scripts)
|
assets.register("scripts", page_scripts)
|
||||||
assets.register("styles", styles)
|
assets.register("styles", page_styling)
|
||||||
|
|
||||||
# BLUEPRINTS
|
# BLUEPRINTS
|
||||||
app.register_blueprint(view_auth.blueprint)
|
app.register_blueprint(view_auth)
|
||||||
app.register_blueprint(view_index.blueprint)
|
app.register_blueprint(view_index)
|
||||||
app.register_blueprint(view_image.blueprint)
|
app.register_blueprint(view_image)
|
||||||
app.register_blueprint(view_group.blueprint)
|
app.register_blueprint(view_group)
|
||||||
app.register_blueprint(view_profile.blueprint)
|
app.register_blueprint(view_profile)
|
||||||
app.register_blueprint(view_settings.blueprint)
|
app.register_blueprint(view_settings)
|
||||||
|
app.register_blueprint(api)
|
||||||
app.register_blueprint(api.blueprint)
|
app.register_blueprint(filters)
|
||||||
|
|
||||||
# FILTERS
|
|
||||||
app.register_blueprint(filters.blueprint)
|
|
||||||
|
|
||||||
# CACHE AND COMPRESS
|
# CACHE AND COMPRESS
|
||||||
cache.init_app(app)
|
cache.init_app(app)
|
||||||
|
|
|
@ -9,16 +9,17 @@ from yaml import safe_load
|
||||||
|
|
||||||
|
|
||||||
# Set dirs
|
# Set dirs
|
||||||
user_dir = platformdirs.user_config_dir("onlylegs")
|
APPLICATION_ROOT = platformdirs.user_config_dir("onlylegs")
|
||||||
instance_dir = os.path.join(user_dir, "instance")
|
|
||||||
|
|
||||||
# Load environment variables
|
# Load environment variables
|
||||||
# print("Loading environment variables...")
|
# print("Loading environment variables...")
|
||||||
load_dotenv(os.path.join(user_dir, ".env"))
|
load_dotenv(os.path.join(APPLICATION_ROOT, ".env"))
|
||||||
|
|
||||||
# Load config from user dir
|
# Load config from user dir
|
||||||
# print("Loading config...")
|
# print("Loading config...")
|
||||||
with open(os.path.join(user_dir, "conf.yml"), encoding="utf-8", mode="r") as file:
|
with open(
|
||||||
|
os.path.join(APPLICATION_ROOT, "conf.yml"), encoding="utf-8", mode="r"
|
||||||
|
) as file:
|
||||||
conf = safe_load(file)
|
conf = safe_load(file)
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,13 +35,13 @@ UPLOAD_CONF = conf["upload"]
|
||||||
WEBSITE_CONF = conf["website"]
|
WEBSITE_CONF = conf["website"]
|
||||||
|
|
||||||
# Directories
|
# Directories
|
||||||
UPLOAD_FOLDER = os.path.join(user_dir, "media", "uploads")
|
UPLOAD_FOLDER = os.path.join(APPLICATION_ROOT, "media", "uploads")
|
||||||
CACHE_FOLDER = os.path.join(user_dir, "media", "cache")
|
CACHE_FOLDER = os.path.join(APPLICATION_ROOT, "media", "cache")
|
||||||
PFP_FOLDER = os.path.join(user_dir, "media", "pfp")
|
PFP_FOLDER = os.path.join(APPLICATION_ROOT, "media", "pfp")
|
||||||
MEDIA_FOLDER = os.path.join(user_dir, "media")
|
MEDIA_FOLDER = os.path.join(APPLICATION_ROOT, "media")
|
||||||
|
|
||||||
# Database
|
# Database
|
||||||
INSTANCE_DIR = instance_dir
|
INSTANCE_DIR = os.path.join(APPLICATION_ROOT, "instance")
|
||||||
MIGRATIONS_DIR = os.path.join(INSTANCE_DIR, "migrations")
|
MIGRATIONS_DIR = os.path.join(INSTANCE_DIR, "migrations")
|
||||||
|
|
||||||
# App
|
# App
|
||||||
|
|
|
@ -14,47 +14,6 @@ function imageFullscreen() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function imageShowOptionsPopup(obj) {
|
function imageShowOptionsPopup(obj) {
|
||||||
// let title = 'Options';
|
|
||||||
// let subtitle = null;
|
|
||||||
//
|
|
||||||
// let body = document.createElement('div');
|
|
||||||
// body.style.cssText = 'display: flex; flex-direction: column; gap: 0.5rem;';
|
|
||||||
//
|
|
||||||
// let copyBtn = document.createElement('button');
|
|
||||||
// copyBtn.classList.add('btn-block');
|
|
||||||
// copyBtn.innerHTML = 'Copy URL';
|
|
||||||
// copyBtn.onclick = () => {
|
|
||||||
// copyToClipboard(window.location.href)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// let downloadBtn = document.createElement('a');
|
|
||||||
// downloadBtn.classList.add('btn-block');
|
|
||||||
// downloadBtn.innerHTML = 'Download';
|
|
||||||
// downloadBtn.href = '/api/media/uploads/' + image_data["filename"];
|
|
||||||
// downloadBtn.download = '';
|
|
||||||
//
|
|
||||||
// body.appendChild(copyBtn);
|
|
||||||
// body.appendChild(downloadBtn);
|
|
||||||
//
|
|
||||||
// if (image_data["owner"]) {
|
|
||||||
// let editBtn = document.createElement('button');
|
|
||||||
// editBtn.classList.add('btn-block');
|
|
||||||
// editBtn.classList.add('critical');
|
|
||||||
// editBtn.innerHTML = 'Edit';
|
|
||||||
// editBtn.onclick = imageEditPopup;
|
|
||||||
//
|
|
||||||
// let deleteBtn = document.createElement('button');
|
|
||||||
// deleteBtn.classList.add('btn-block');
|
|
||||||
// deleteBtn.classList.add('critical');
|
|
||||||
// deleteBtn.innerHTML = 'Delete';
|
|
||||||
// deleteBtn.onclick = imageDeletePopup;
|
|
||||||
//
|
|
||||||
// body.appendChild(editBtn);
|
|
||||||
// body.appendChild(deleteBtn);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// popupShow(title, subtitle, body, [popupCancelButton]);
|
|
||||||
|
|
||||||
showContextMenu(obj, [
|
showContextMenu(obj, [
|
||||||
{
|
{
|
||||||
'value': 'Edit',
|
'value': 'Edit',
|
||||||
|
|
|
@ -141,41 +141,14 @@ function clearUpload() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// function createJob(file) {
|
|
||||||
// jobContainer = document.createElement("div");
|
|
||||||
// jobContainer.classList.add("job");
|
|
||||||
|
|
||||||
// jobStatus = document.createElement("span");
|
|
||||||
// jobStatus.classList.add("job__status");
|
|
||||||
// jobStatus.innerHTML = "Uploading...";
|
|
||||||
|
|
||||||
// jobProgress = document.createElement("span");
|
|
||||||
// jobProgress.classList.add("progress");
|
|
||||||
|
|
||||||
// jobImg = document.createElement("img");
|
|
||||||
// jobImg.src = URL.createObjectURL(file);
|
|
||||||
|
|
||||||
// jobImgFilter = document.createElement("span");
|
|
||||||
// jobImgFilter.classList.add("img-filter");
|
|
||||||
|
|
||||||
// jobContainer.appendChild(jobStatus);
|
|
||||||
// jobContainer.appendChild(jobProgress);
|
|
||||||
// jobContainer.appendChild(jobImg);
|
|
||||||
// jobContainer.appendChild(jobImgFilter);
|
|
||||||
|
|
||||||
// return jobContainer;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
// Function to upload images
|
// Function to upload images
|
||||||
const uploadTab = document.querySelector(".upload-panel");
|
const uploadTab = document.querySelector(".upload-panel");
|
||||||
|
|
||||||
if (!uploadTab) { return; } // If upload tab doesn't exist, don't run this code :3
|
if (!uploadTab) { return }
|
||||||
|
|
||||||
const uploadTabDrag = uploadTab.querySelector("#dragIndicator");
|
const uploadTabDrag = uploadTab.querySelector("#dragIndicator");
|
||||||
const uploadForm = uploadTab.querySelector('#uploadForm');
|
const uploadForm = uploadTab.querySelector('#uploadForm');
|
||||||
// let jobList = document.querySelector(".upload-jobs");
|
|
||||||
|
|
||||||
const fileDrop = uploadForm.querySelector('.fileDrop-block');
|
const fileDrop = uploadForm.querySelector('.fileDrop-block');
|
||||||
const fileDropTitle = fileDrop.querySelector('.status');
|
const fileDropTitle = fileDrop.querySelector('.status');
|
||||||
|
@ -228,54 +201,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
formData.append("description", fileDescription.value);
|
formData.append("description", fileDescription.value);
|
||||||
formData.append("tags", fileTags.value);
|
formData.append("tags", fileTags.value);
|
||||||
|
|
||||||
// jobItem = createJob(fileUpload.files[0]);
|
|
||||||
// jobStatus = jobItem.querySelector(".job__status");
|
|
||||||
|
|
||||||
// Upload the information
|
|
||||||
// $.ajax({
|
|
||||||
// url: '/api/upload',
|
|
||||||
// type: 'post',
|
|
||||||
// data: formData,
|
|
||||||
// contentType: false,
|
|
||||||
// processData: false,
|
|
||||||
// beforeSend: function () {
|
|
||||||
// // Add job to list
|
|
||||||
// jobList.appendChild(jobItem);
|
|
||||||
// },
|
|
||||||
// success: function (response) {
|
|
||||||
// jobItem.classList.add("success");
|
|
||||||
// jobStatus.innerHTML = "Uploaded successfully";
|
|
||||||
// if (!document.querySelector(".upload-panel").classList.contains("open")) {
|
|
||||||
// addNotification("Image uploaded successfully", 1);
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// error: function (response) {
|
|
||||||
// jobItem.classList.add("critical");
|
|
||||||
// switch (response.status) {
|
|
||||||
// case 500:
|
|
||||||
// jobStatus.innerHTML = "Server exploded, F's in chat";
|
|
||||||
// break;
|
|
||||||
// case 400:
|
|
||||||
// case 404:
|
|
||||||
// jobStatus.innerHTML = "Error uploading. Blame yourself";
|
|
||||||
// break;
|
|
||||||
// case 403:
|
|
||||||
// jobStatus.innerHTML = "None but devils play past here...";
|
|
||||||
// break;
|
|
||||||
// case 413:
|
|
||||||
// jobStatus.innerHTML = "File too large!!!!!!";
|
|
||||||
// break;
|
|
||||||
// default:
|
|
||||||
// jobStatus.innerHTML = "Error uploading file, blame someone";
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// if (!document.querySelector(".upload-panel").classList.contains("open")) {
|
|
||||||
// addNotification("Error uploading file", 2);
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// });
|
|
||||||
|
|
||||||
|
|
||||||
fetch('/api/media/upload', {
|
fetch('/api/media/upload', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: formData
|
body: formData
|
||||||
|
|
|
@ -1,23 +1,15 @@
|
||||||
@keyframes notificationTimeout
|
@keyframes notificationTimeout
|
||||||
0%
|
0%
|
||||||
left: -100%
|
width: 0
|
||||||
height: 3px
|
|
||||||
90%
|
|
||||||
left: 0%
|
|
||||||
height: 3px
|
|
||||||
95%
|
|
||||||
left: 0%
|
|
||||||
height: 0
|
|
||||||
100%
|
100%
|
||||||
left: 0%
|
width: 100%
|
||||||
height: 0
|
|
||||||
|
|
||||||
@mixin notification($color)
|
@mixin notification($color)
|
||||||
color: RGB($color)
|
color: RGB($color)
|
||||||
|
|
||||||
&::after
|
&::after
|
||||||
background-color: RGB($color)
|
background-color: RGB($color)
|
||||||
|
|
||||||
.notifications
|
.notifications
|
||||||
margin: 0
|
margin: 0
|
||||||
padding: 0
|
padding: 0
|
||||||
|
@ -60,17 +52,17 @@
|
||||||
&::after
|
&::after
|
||||||
content: ""
|
content: ""
|
||||||
|
|
||||||
width: 100%
|
width: 0
|
||||||
height: 3px
|
height: 3px
|
||||||
|
|
||||||
position: absolute
|
position: absolute
|
||||||
bottom: 0px
|
bottom: 0
|
||||||
left: 0px
|
left: 0
|
||||||
|
|
||||||
background-color: RGB($fg-white)
|
background-color: RGB($fg-white)
|
||||||
|
|
||||||
z-index: +2
|
z-index: +2
|
||||||
animation: notificationTimeout 5.1s linear
|
animation: notificationTimeout 5.1s ease-out forwards
|
||||||
|
|
||||||
&.success
|
&.success
|
||||||
@include notification($success)
|
@include notification($success)
|
||||||
|
@ -89,7 +81,7 @@
|
||||||
margin: 0
|
margin: 0
|
||||||
max-height: 0
|
max-height: 0
|
||||||
opacity: 0
|
opacity: 0
|
||||||
transform: translateX(100%)
|
transform: translateY(1rem)
|
||||||
transition: all 0.4s ease-in-out, max-height 0.2s ease-in-out
|
transition: all 0.4s ease-in-out, max-height 0.2s ease-in-out
|
||||||
|
|
||||||
.sniffle__notification-icon
|
.sniffle__notification-icon
|
||||||
|
@ -133,10 +125,6 @@
|
||||||
|
|
||||||
.sniffle__notification
|
.sniffle__notification
|
||||||
width: 100%
|
width: 100%
|
||||||
|
|
||||||
&.hide
|
|
||||||
opacity: 0
|
|
||||||
transform: translateY(1rem)
|
|
||||||
|
|
||||||
.sniffle__notification-time
|
.sniffle__notification-time
|
||||||
width: 100%
|
width: 100%
|
||||||
|
|
|
@ -60,16 +60,18 @@ body
|
||||||
padding: 0 0 3.5rem 0
|
padding: 0 0 3.5rem 0
|
||||||
|
|
||||||
main
|
main
|
||||||
|
margin: 0 0.5rem 0.5rem 0
|
||||||
display: flex
|
display: flex
|
||||||
flex-direction: column
|
flex-direction: column
|
||||||
position: relative
|
position: relative
|
||||||
background: RGBA($white, 1)
|
background: RGBA($white, 1)
|
||||||
color: RGB($fg-black)
|
color: RGB($fg-black)
|
||||||
border-top-left-radius: $rad
|
border-radius: $rad
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
@media (max-width: $breakpoint)
|
@media (max-width: $breakpoint)
|
||||||
main
|
main
|
||||||
border-top-left-radius: 0
|
margin: 0
|
||||||
|
border-radius: 0
|
||||||
|
|
||||||
.error-page
|
.error-page
|
||||||
min-height: 100%
|
min-height: 100%
|
||||||
|
|
156
onlylegs/utils/startup.py
Normal file
156
onlylegs/utils/startup.py
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
"""
|
||||||
|
OnlyLegs - Setup
|
||||||
|
Runs when the app detects that there is no user directory
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import platformdirs
|
||||||
|
import yaml
|
||||||
|
from werkzeug.security import generate_password_hash
|
||||||
|
from onlylegs.extensions import db
|
||||||
|
from onlylegs.models import Users
|
||||||
|
|
||||||
|
|
||||||
|
APPLICATION_ROOT = platformdirs.user_config_dir("onlyLegs")
|
||||||
|
REQUIRED_DIRS = {
|
||||||
|
"root": APPLICATION_ROOT,
|
||||||
|
"instance": os.path.join(APPLICATION_ROOT, "instance"),
|
||||||
|
"media": os.path.join(APPLICATION_ROOT, "media"),
|
||||||
|
"uploads": os.path.join(APPLICATION_ROOT, "media", "uploads"),
|
||||||
|
"cache": os.path.join(APPLICATION_ROOT, "media", "cache"),
|
||||||
|
"pfp": os.path.join(APPLICATION_ROOT, "media", "pfp"),
|
||||||
|
}
|
||||||
|
|
||||||
|
EMAIL_REGEX = re.compile(r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b")
|
||||||
|
USERNAME_REGEX = re.compile(r"\b[A-Za-z0-9._%+-]+\b")
|
||||||
|
|
||||||
|
|
||||||
|
def check_dirs():
|
||||||
|
"""
|
||||||
|
Create the user directory
|
||||||
|
"""
|
||||||
|
|
||||||
|
for directory in REQUIRED_DIRS.values():
|
||||||
|
if os.path.exists(directory):
|
||||||
|
print("User directory already exists at:", directory)
|
||||||
|
return
|
||||||
|
os.makedirs(directory)
|
||||||
|
print("Created directory at:", directory)
|
||||||
|
|
||||||
|
|
||||||
|
def check_env():
|
||||||
|
"""
|
||||||
|
Create the .env file with default values
|
||||||
|
"""
|
||||||
|
if os.path.exists(os.path.join(APPLICATION_ROOT, ".env")):
|
||||||
|
print("Environment file already exists at:", APPLICATION_ROOT)
|
||||||
|
return
|
||||||
|
|
||||||
|
env_conf = {
|
||||||
|
"FLASK_SECRET": os.urandom(32).hex(),
|
||||||
|
}
|
||||||
|
|
||||||
|
with open(
|
||||||
|
os.path.join(APPLICATION_ROOT, ".env"), encoding="utf-8", mode="w+"
|
||||||
|
) as file:
|
||||||
|
for key, value in env_conf.items():
|
||||||
|
file.write(key + "=" + value + "\n")
|
||||||
|
|
||||||
|
print(
|
||||||
|
"####################################################"
|
||||||
|
"# A NEW KEY WAS GENERATED FOR YOU! PLEASE NOTE #"
|
||||||
|
"# DOWN THE FLASK_SECRET KEY LOCATED IN YOUR #"
|
||||||
|
"# ~/.config/onlylegs/.env FOLDER! LOOSING THIS KEY #"
|
||||||
|
"# WILL RESULT IN YOU BEING UNABLE TO LOG IN! #"
|
||||||
|
"####################################################",
|
||||||
|
sep="\n",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def check_conf():
|
||||||
|
"""
|
||||||
|
Create the YAML config file with default values
|
||||||
|
"""
|
||||||
|
if os.path.exists(os.path.join(APPLICATION_ROOT, "conf.yml")):
|
||||||
|
print("Config file already exists at:", APPLICATION_ROOT)
|
||||||
|
return
|
||||||
|
|
||||||
|
can_continue = False
|
||||||
|
username = "admin"
|
||||||
|
name = "Admin"
|
||||||
|
email = "admin@example.com"
|
||||||
|
|
||||||
|
print("No config file found, please enter the following information:")
|
||||||
|
while can_continue:
|
||||||
|
username = input("Admin username: ")
|
||||||
|
name = input("Admin name: ")
|
||||||
|
email = input("Admin email: ")
|
||||||
|
|
||||||
|
if not username or not USERNAME_REGEX.match(username):
|
||||||
|
print("Username is invalid!")
|
||||||
|
if not name:
|
||||||
|
print("Name is invalid!")
|
||||||
|
if not email or not EMAIL_REGEX.match(email):
|
||||||
|
print("Email is invalid!")
|
||||||
|
|
||||||
|
# Check if user is happy with the values
|
||||||
|
is_correct = input("Is this correct? (Y/n): ").lower()
|
||||||
|
if is_correct == "y" or is_correct == "":
|
||||||
|
can_continue = True
|
||||||
|
|
||||||
|
yaml_conf = {
|
||||||
|
"admin": {
|
||||||
|
"name": name,
|
||||||
|
"username": username,
|
||||||
|
"email": email,
|
||||||
|
},
|
||||||
|
"upload": {
|
||||||
|
"allowed-extensions": {
|
||||||
|
"jpg": "jpeg",
|
||||||
|
"jpeg": "jpeg",
|
||||||
|
"png": "png",
|
||||||
|
"webp": "webp",
|
||||||
|
},
|
||||||
|
"max-size": 69,
|
||||||
|
"max-load": 50,
|
||||||
|
"rename": "GWA_{{username}}_{{time}}",
|
||||||
|
},
|
||||||
|
"website": {
|
||||||
|
"name": "OnlyLegs",
|
||||||
|
"motto": "A gallery built for fast and simple image management!",
|
||||||
|
"language": "en",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
with open(
|
||||||
|
os.path.join(APPLICATION_ROOT, "conf.yml"), encoding="utf-8", mode="w+"
|
||||||
|
) as file:
|
||||||
|
yaml.dump(yaml_conf, file, default_flow_style=False)
|
||||||
|
|
||||||
|
print(
|
||||||
|
"####################################################"
|
||||||
|
"# A NEW CONFIG HAS BEEN GENERATED AT: #"
|
||||||
|
"# ~/.config/onlylegs/conf.yml #"
|
||||||
|
"####################################################",
|
||||||
|
sep="\n",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def make_admin_user(app):
|
||||||
|
username = app.config["ADMIN_CONF"]["username"]
|
||||||
|
email = app.config["ADMIN_CONF"]["email"]
|
||||||
|
password = generate_password_hash("changeme!", method="scrypt")
|
||||||
|
|
||||||
|
with app.app_context():
|
||||||
|
db.create_all()
|
||||||
|
db.session.add(Users(username=username, email=email, password=password))
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
print(
|
||||||
|
"####################################################"
|
||||||
|
"# DEFAULT ADMIN USER GENERATED WITH GIVEN USERNAME #"
|
||||||
|
'# THE DEFAULT PASSWORD "changeme!" HAS BEEN USED, #'
|
||||||
|
"# PLEASE RESET IT IN THE SETTINGS! #"
|
||||||
|
"####################################################",
|
||||||
|
sep="\n",
|
||||||
|
)
|
118
poetry.lock
generated
118
poetry.lock
generated
|
@ -1,4 +1,4 @@
|
||||||
# This file is automatically @generated by Poetry and should not be changed by hand.
|
# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand.
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "alembic"
|
name = "alembic"
|
||||||
|
@ -727,6 +727,22 @@ files = [
|
||||||
{file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"},
|
{file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "material-color-utilities-python"
|
||||||
|
version = "0.1.5"
|
||||||
|
description = "Python port of material-color-utilities used for Material You colors"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
files = [
|
||||||
|
{file = "material-color-utilities-python-0.1.5.tar.gz", hash = "sha256:3c6f02e7ce70595885447bdef37cf76fd3628c7c95fa2198d8174c269c951fae"},
|
||||||
|
{file = "material_color_utilities_python-0.1.5-py2.py3-none-any.whl", hash = "sha256:48abd8695a1355ab3ad43fe314ca8664c66282a86fbf94a717571273bf422bdf"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
Pillow = ">=9.2.0,<10.0.0"
|
||||||
|
regex = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mccabe"
|
name = "mccabe"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
|
@ -966,6 +982,104 @@ files = [
|
||||||
{file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
|
{file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "2023.8.8"
|
||||||
|
description = "Alternative regular expression module, to replace re."
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6"
|
||||||
|
files = [
|
||||||
|
{file = "regex-2023.8.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:88900f521c645f784260a8d346e12a1590f79e96403971241e64c3a265c8ecdb"},
|
||||||
|
{file = "regex-2023.8.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3611576aff55918af2697410ff0293d6071b7e00f4b09e005d614686ac4cd57c"},
|
||||||
|
{file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8a0ccc8f2698f120e9e5742f4b38dc944c38744d4bdfc427616f3a163dd9de5"},
|
||||||
|
{file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c662a4cbdd6280ee56f841f14620787215a171c4e2d1744c9528bed8f5816c96"},
|
||||||
|
{file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cf0633e4a1b667bfe0bb10b5e53fe0d5f34a6243ea2530eb342491f1adf4f739"},
|
||||||
|
{file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:551ad543fa19e94943c5b2cebc54c73353ffff08228ee5f3376bd27b3d5b9800"},
|
||||||
|
{file = "regex-2023.8.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54de2619f5ea58474f2ac211ceea6b615af2d7e4306220d4f3fe690c91988a61"},
|
||||||
|
{file = "regex-2023.8.8-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5ec4b3f0aebbbe2fc0134ee30a791af522a92ad9f164858805a77442d7d18570"},
|
||||||
|
{file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3ae646c35cb9f820491760ac62c25b6d6b496757fda2d51be429e0e7b67ae0ab"},
|
||||||
|
{file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ca339088839582d01654e6f83a637a4b8194d0960477b9769d2ff2cfa0fa36d2"},
|
||||||
|
{file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:d9b6627408021452dcd0d2cdf8da0534e19d93d070bfa8b6b4176f99711e7f90"},
|
||||||
|
{file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:bd3366aceedf274f765a3a4bc95d6cd97b130d1dda524d8f25225d14123c01db"},
|
||||||
|
{file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7aed90a72fc3654fba9bc4b7f851571dcc368120432ad68b226bd593f3f6c0b7"},
|
||||||
|
{file = "regex-2023.8.8-cp310-cp310-win32.whl", hash = "sha256:80b80b889cb767cc47f31d2b2f3dec2db8126fbcd0cff31b3925b4dc6609dcdb"},
|
||||||
|
{file = "regex-2023.8.8-cp310-cp310-win_amd64.whl", hash = "sha256:b82edc98d107cbc7357da7a5a695901b47d6eb0420e587256ba3ad24b80b7d0b"},
|
||||||
|
{file = "regex-2023.8.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1e7d84d64c84ad97bf06f3c8cb5e48941f135ace28f450d86af6b6512f1c9a71"},
|
||||||
|
{file = "regex-2023.8.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ce0f9fbe7d295f9922c0424a3637b88c6c472b75eafeaff6f910494a1fa719ef"},
|
||||||
|
{file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06c57e14ac723b04458df5956cfb7e2d9caa6e9d353c0b4c7d5d54fcb1325c46"},
|
||||||
|
{file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e7a9aaa5a1267125eef22cef3b63484c3241aaec6f48949b366d26c7250e0357"},
|
||||||
|
{file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b7408511fca48a82a119d78a77c2f5eb1b22fe88b0d2450ed0756d194fe7a9a"},
|
||||||
|
{file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14dc6f2d88192a67d708341f3085df6a4f5a0c7b03dec08d763ca2cd86e9f559"},
|
||||||
|
{file = "regex-2023.8.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48c640b99213643d141550326f34f0502fedb1798adb3c9eb79650b1ecb2f177"},
|
||||||
|
{file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0085da0f6c6393428bf0d9c08d8b1874d805bb55e17cb1dfa5ddb7cfb11140bf"},
|
||||||
|
{file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:964b16dcc10c79a4a2be9f1273fcc2684a9eedb3906439720598029a797b46e6"},
|
||||||
|
{file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7ce606c14bb195b0e5108544b540e2c5faed6843367e4ab3deb5c6aa5e681208"},
|
||||||
|
{file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:40f029d73b10fac448c73d6eb33d57b34607f40116e9f6e9f0d32e9229b147d7"},
|
||||||
|
{file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3b8e6ea6be6d64104d8e9afc34c151926f8182f84e7ac290a93925c0db004bfd"},
|
||||||
|
{file = "regex-2023.8.8-cp311-cp311-win32.whl", hash = "sha256:942f8b1f3b223638b02df7df79140646c03938d488fbfb771824f3d05fc083a8"},
|
||||||
|
{file = "regex-2023.8.8-cp311-cp311-win_amd64.whl", hash = "sha256:51d8ea2a3a1a8fe4f67de21b8b93757005213e8ac3917567872f2865185fa7fb"},
|
||||||
|
{file = "regex-2023.8.8-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e951d1a8e9963ea51efd7f150450803e3b95db5939f994ad3d5edac2b6f6e2b4"},
|
||||||
|
{file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:704f63b774218207b8ccc6c47fcef5340741e5d839d11d606f70af93ee78e4d4"},
|
||||||
|
{file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:22283c769a7b01c8ac355d5be0715bf6929b6267619505e289f792b01304d898"},
|
||||||
|
{file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91129ff1bb0619bc1f4ad19485718cc623a2dc433dff95baadbf89405c7f6b57"},
|
||||||
|
{file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de35342190deb7b866ad6ba5cbcccb2d22c0487ee0cbb251efef0843d705f0d4"},
|
||||||
|
{file = "regex-2023.8.8-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b993b6f524d1e274a5062488a43e3f9f8764ee9745ccd8e8193df743dbe5ee61"},
|
||||||
|
{file = "regex-2023.8.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3026cbcf11d79095a32d9a13bbc572a458727bd5b1ca332df4a79faecd45281c"},
|
||||||
|
{file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:293352710172239bf579c90a9864d0df57340b6fd21272345222fb6371bf82b3"},
|
||||||
|
{file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:d909b5a3fff619dc7e48b6b1bedc2f30ec43033ba7af32f936c10839e81b9217"},
|
||||||
|
{file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:3d370ff652323c5307d9c8e4c62efd1956fb08051b0e9210212bc51168b4ff56"},
|
||||||
|
{file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:b076da1ed19dc37788f6a934c60adf97bd02c7eea461b73730513921a85d4235"},
|
||||||
|
{file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:e9941a4ada58f6218694f382e43fdd256e97615db9da135e77359da257a7168b"},
|
||||||
|
{file = "regex-2023.8.8-cp36-cp36m-win32.whl", hash = "sha256:a8c65c17aed7e15a0c824cdc63a6b104dfc530f6fa8cb6ac51c437af52b481c7"},
|
||||||
|
{file = "regex-2023.8.8-cp36-cp36m-win_amd64.whl", hash = "sha256:aadf28046e77a72f30dcc1ab185639e8de7f4104b8cb5c6dfa5d8ed860e57236"},
|
||||||
|
{file = "regex-2023.8.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:423adfa872b4908843ac3e7a30f957f5d5282944b81ca0a3b8a7ccbbfaa06103"},
|
||||||
|
{file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ae594c66f4a7e1ea67232a0846649a7c94c188d6c071ac0210c3e86a5f92109"},
|
||||||
|
{file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e51c80c168074faa793685656c38eb7a06cbad7774c8cbc3ea05552d615393d8"},
|
||||||
|
{file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:09b7f4c66aa9d1522b06e31a54f15581c37286237208df1345108fcf4e050c18"},
|
||||||
|
{file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e73e5243af12d9cd6a9d6a45a43570dbe2e5b1cdfc862f5ae2b031e44dd95a8"},
|
||||||
|
{file = "regex-2023.8.8-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:941460db8fe3bd613db52f05259c9336f5a47ccae7d7def44cc277184030a116"},
|
||||||
|
{file = "regex-2023.8.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f0ccf3e01afeb412a1a9993049cb160d0352dba635bbca7762b2dc722aa5742a"},
|
||||||
|
{file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:2e9216e0d2cdce7dbc9be48cb3eacb962740a09b011a116fd7af8c832ab116ca"},
|
||||||
|
{file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:5cd9cd7170459b9223c5e592ac036e0704bee765706445c353d96f2890e816c8"},
|
||||||
|
{file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:4873ef92e03a4309b3ccd8281454801b291b689f6ad45ef8c3658b6fa761d7ac"},
|
||||||
|
{file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:239c3c2a339d3b3ddd51c2daef10874410917cd2b998f043c13e2084cb191684"},
|
||||||
|
{file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1005c60ed7037be0d9dea1f9c53cc42f836188227366370867222bda4c3c6bd7"},
|
||||||
|
{file = "regex-2023.8.8-cp37-cp37m-win32.whl", hash = "sha256:e6bd1e9b95bc5614a7a9c9c44fde9539cba1c823b43a9f7bc11266446dd568e3"},
|
||||||
|
{file = "regex-2023.8.8-cp37-cp37m-win_amd64.whl", hash = "sha256:9a96edd79661e93327cfeac4edec72a4046e14550a1d22aa0dd2e3ca52aec921"},
|
||||||
|
{file = "regex-2023.8.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f2181c20ef18747d5f4a7ea513e09ea03bdd50884a11ce46066bb90fe4213675"},
|
||||||
|
{file = "regex-2023.8.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a2ad5add903eb7cdde2b7c64aaca405f3957ab34f16594d2b78d53b8b1a6a7d6"},
|
||||||
|
{file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9233ac249b354c54146e392e8a451e465dd2d967fc773690811d3a8c240ac601"},
|
||||||
|
{file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:920974009fb37b20d32afcdf0227a2e707eb83fe418713f7a8b7de038b870d0b"},
|
||||||
|
{file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2b6c5dfe0929b6c23dde9624483380b170b6e34ed79054ad131b20203a1a63"},
|
||||||
|
{file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96979d753b1dc3b2169003e1854dc67bfc86edf93c01e84757927f810b8c3c93"},
|
||||||
|
{file = "regex-2023.8.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ae54a338191e1356253e7883d9d19f8679b6143703086245fb14d1f20196be9"},
|
||||||
|
{file = "regex-2023.8.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2162ae2eb8b079622176a81b65d486ba50b888271302190870b8cc488587d280"},
|
||||||
|
{file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c884d1a59e69e03b93cf0dfee8794c63d7de0ee8f7ffb76e5f75be8131b6400a"},
|
||||||
|
{file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf9273e96f3ee2ac89ffcb17627a78f78e7516b08f94dc435844ae72576a276e"},
|
||||||
|
{file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:83215147121e15d5f3a45d99abeed9cf1fe16869d5c233b08c56cdf75f43a504"},
|
||||||
|
{file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:3f7454aa427b8ab9101f3787eb178057c5250478e39b99540cfc2b889c7d0586"},
|
||||||
|
{file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0640913d2c1044d97e30d7c41728195fc37e54d190c5385eacb52115127b882"},
|
||||||
|
{file = "regex-2023.8.8-cp38-cp38-win32.whl", hash = "sha256:0c59122ceccb905a941fb23b087b8eafc5290bf983ebcb14d2301febcbe199c7"},
|
||||||
|
{file = "regex-2023.8.8-cp38-cp38-win_amd64.whl", hash = "sha256:c12f6f67495ea05c3d542d119d270007090bad5b843f642d418eb601ec0fa7be"},
|
||||||
|
{file = "regex-2023.8.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:82cd0a69cd28f6cc3789cc6adeb1027f79526b1ab50b1f6062bbc3a0ccb2dbc3"},
|
||||||
|
{file = "regex-2023.8.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bb34d1605f96a245fc39790a117ac1bac8de84ab7691637b26ab2c5efb8f228c"},
|
||||||
|
{file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:987b9ac04d0b38ef4f89fbc035e84a7efad9cdd5f1e29024f9289182c8d99e09"},
|
||||||
|
{file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9dd6082f4e2aec9b6a0927202c85bc1b09dcab113f97265127c1dc20e2e32495"},
|
||||||
|
{file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7eb95fe8222932c10d4436e7a6f7c99991e3fdd9f36c949eff16a69246dee2dc"},
|
||||||
|
{file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7098c524ba9f20717a56a8d551d2ed491ea89cbf37e540759ed3b776a4f8d6eb"},
|
||||||
|
{file = "regex-2023.8.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b694430b3f00eb02c594ff5a16db30e054c1b9589a043fe9174584c6efa8033"},
|
||||||
|
{file = "regex-2023.8.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b2aeab3895d778155054abea5238d0eb9a72e9242bd4b43f42fd911ef9a13470"},
|
||||||
|
{file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:988631b9d78b546e284478c2ec15c8a85960e262e247b35ca5eaf7ee22f6050a"},
|
||||||
|
{file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:67ecd894e56a0c6108ec5ab1d8fa8418ec0cff45844a855966b875d1039a2e34"},
|
||||||
|
{file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:14898830f0a0eb67cae2bbbc787c1a7d6e34ecc06fbd39d3af5fe29a4468e2c9"},
|
||||||
|
{file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:f2200e00b62568cfd920127782c61bc1c546062a879cdc741cfcc6976668dfcf"},
|
||||||
|
{file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9691a549c19c22d26a4f3b948071e93517bdf86e41b81d8c6ac8a964bb71e5a6"},
|
||||||
|
{file = "regex-2023.8.8-cp39-cp39-win32.whl", hash = "sha256:6ab2ed84bf0137927846b37e882745a827458689eb969028af8032b1b3dac78e"},
|
||||||
|
{file = "regex-2023.8.8-cp39-cp39-win_amd64.whl", hash = "sha256:5543c055d8ec7801901e1193a51570643d6a6ab8751b1f7dd9af71af467538bb"},
|
||||||
|
{file = "regex-2023.8.8.tar.gz", hash = "sha256:fcbdc5f2b0f1cd0f6a56cdb46fe41d2cce1e644e3b68832f3eeebc5fb0f7712e"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "setuptools"
|
name = "setuptools"
|
||||||
version = "68.0.0"
|
version = "68.0.0"
|
||||||
|
@ -1232,4 +1346,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.8"
|
python-versions = "^3.8"
|
||||||
content-hash = "96ec0d1f7b512afb05455262fa2de8c4f862bf68fdae513f8552dc30c6e5ab49"
|
content-hash = "11735dbbdd45dcc5085a04dbbd4e786dd8aeb4ba743f0c20294861e7b4c35dd0"
|
||||||
|
|
|
@ -28,6 +28,7 @@ cssmin = "^0.2.0"
|
||||||
pylint = "^2.16.3"
|
pylint = "^2.16.3"
|
||||||
black = "^23.3.0"
|
black = "^23.3.0"
|
||||||
cachetools = "^5.3.0"
|
cachetools = "^5.3.0"
|
||||||
|
material-color-utilities-python = "^0.1.5"
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core"]
|
requires = ["poetry-core"]
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
"""
|
|
||||||
Startup arguments for the OnlyLegs gallery
|
|
||||||
|
|
||||||
-p, --port: Port to run on (default: 5000)
|
|
||||||
-a, --address: Address to run on (default: 127.0.0.0)
|
|
||||||
-w, --workers: Number of workers to run (default: 4)
|
|
||||||
|
|
||||||
-d, --debug: Run as Flask app in debug mode (default: False)
|
|
||||||
-S, --scream: Show verbose output (default: False)
|
|
||||||
-h, --help: Show a help message
|
|
||||||
"""
|
|
||||||
|
|
||||||
import argparse
|
|
||||||
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description="Run the OnlyLegs gallery")
|
|
||||||
parser.add_argument("-p", "--port", type=int, default=5000, help="Port to run on")
|
|
||||||
parser.add_argument(
|
|
||||||
"-a", "--address", type=str, default="127.0.0.0", help="Address to run on"
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"-w", "--workers", type=int, default=4, help="Number of workers to run"
|
|
||||||
)
|
|
||||||
parser.add_argument(
|
|
||||||
"-d", "--debug", action="store_true", help="Run as Flask app in debug mode"
|
|
||||||
)
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
|
|
||||||
PORT = args.port
|
|
||||||
ADDRESS = args.address
|
|
||||||
WORKERS = args.workers
|
|
||||||
DEBUG = args.debug
|
|
|
@ -1,156 +0,0 @@
|
||||||
"""
|
|
||||||
OnlyLegs - Setup
|
|
||||||
Runs when the app detects that there is no user directory
|
|
||||||
"""
|
|
||||||
import os
|
|
||||||
import logging
|
|
||||||
import re
|
|
||||||
import platformdirs
|
|
||||||
import yaml
|
|
||||||
|
|
||||||
|
|
||||||
USER_DIR = platformdirs.user_config_dir("onlylegs")
|
|
||||||
|
|
||||||
|
|
||||||
class Configuration:
|
|
||||||
"""
|
|
||||||
Setup the application on first run
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
"""
|
|
||||||
Main setup function
|
|
||||||
"""
|
|
||||||
print("Running startup checks...")
|
|
||||||
|
|
||||||
# Check if the user directory exists
|
|
||||||
if not os.path.exists(USER_DIR):
|
|
||||||
self.make_dir()
|
|
||||||
|
|
||||||
# Check if the .env file exists
|
|
||||||
if not os.path.exists(os.path.join(USER_DIR, ".env")):
|
|
||||||
self.make_env()
|
|
||||||
|
|
||||||
# Check if the conf.yml file exists
|
|
||||||
if not os.path.exists(os.path.join(USER_DIR, "conf.yml")):
|
|
||||||
self.make_yaml()
|
|
||||||
|
|
||||||
# Load the config files
|
|
||||||
self.logging_config()
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def make_dir():
|
|
||||||
"""
|
|
||||||
Create the user directory
|
|
||||||
"""
|
|
||||||
os.makedirs(USER_DIR)
|
|
||||||
os.makedirs(os.path.join(USER_DIR, "instance"))
|
|
||||||
os.makedirs(os.path.join(USER_DIR, "media"))
|
|
||||||
os.makedirs(os.path.join(USER_DIR, "media", "uploads"))
|
|
||||||
os.makedirs(os.path.join(USER_DIR, "media", "cache"))
|
|
||||||
os.makedirs(os.path.join(USER_DIR, "media", "pfp"))
|
|
||||||
|
|
||||||
print("Created user directory at:", USER_DIR)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def make_env():
|
|
||||||
"""
|
|
||||||
Create the .env file with default values
|
|
||||||
"""
|
|
||||||
env_conf = {
|
|
||||||
"FLASK_SECRET": os.urandom(32).hex(),
|
|
||||||
}
|
|
||||||
|
|
||||||
with open(os.path.join(USER_DIR, ".env"), encoding="utf-8", mode="w+") as file:
|
|
||||||
for key, value in env_conf.items():
|
|
||||||
file.write(f"{key}={value}\n")
|
|
||||||
|
|
||||||
print(
|
|
||||||
"""
|
|
||||||
####################################################
|
|
||||||
# A NEW KEY WAS GENERATED FOR YOU! PLEASE NOTE #
|
|
||||||
# DOWN THE FLASK_SECRET KEY LOCATED IN YOUR #
|
|
||||||
# .config/onlylegs/.env FOLDER! LOOSING THIS KEY #
|
|
||||||
# WILL RESULT IN YOU BEING UNABLE TO LOG IN! #
|
|
||||||
####################################################
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def make_yaml():
|
|
||||||
"""
|
|
||||||
Create the YAML config file with default values
|
|
||||||
"""
|
|
||||||
is_correct = False
|
|
||||||
email_regex = re.compile(r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b")
|
|
||||||
username_regex = re.compile(r"\b[A-Za-z0-9._%+-]+\b")
|
|
||||||
|
|
||||||
print("\nNo config file found, please enter the following information:")
|
|
||||||
while not is_correct:
|
|
||||||
username = input("Admin username: ")
|
|
||||||
name = input("Admin name: ")
|
|
||||||
email = input("Admin email: ")
|
|
||||||
|
|
||||||
# Check if the values are valid
|
|
||||||
if not username or not username_regex.match(username):
|
|
||||||
print("Username is invalid!")
|
|
||||||
continue
|
|
||||||
|
|
||||||
if not name:
|
|
||||||
print("Name is invalid!")
|
|
||||||
continue
|
|
||||||
|
|
||||||
if not email or not email_regex.match(email):
|
|
||||||
print("Email is invalid!")
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Check if user is happy with the values
|
|
||||||
if input("Is this correct? (y/n): ").lower() == "y":
|
|
||||||
is_correct = True
|
|
||||||
|
|
||||||
yaml_conf = {
|
|
||||||
"admin": {
|
|
||||||
"name": name,
|
|
||||||
"username": username,
|
|
||||||
"email": email,
|
|
||||||
},
|
|
||||||
"upload": {
|
|
||||||
"allowed-extensions": {
|
|
||||||
"jpg": "jpeg",
|
|
||||||
"jpeg": "jpeg",
|
|
||||||
"png": "png",
|
|
||||||
"webp": "webp",
|
|
||||||
},
|
|
||||||
"max-size": 69,
|
|
||||||
"max-load": 50,
|
|
||||||
"rename": "GWA_{{username}}_{{time}}",
|
|
||||||
},
|
|
||||||
"website": {
|
|
||||||
"name": "OnlyLegs",
|
|
||||||
"motto": "A gallery built for fast and simple image management!",
|
|
||||||
"language": "en",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
with open(
|
|
||||||
os.path.join(USER_DIR, "conf.yml"), encoding="utf-8", mode="w+"
|
|
||||||
) as file:
|
|
||||||
yaml.dump(yaml_conf, file, default_flow_style=False)
|
|
||||||
|
|
||||||
print(
|
|
||||||
"Generated config file, you can change these values in the settings of the app"
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def logging_config():
|
|
||||||
"""
|
|
||||||
Set the logging config
|
|
||||||
"""
|
|
||||||
logging.getLogger("werkzeug").disabled = True
|
|
||||||
logging.basicConfig(
|
|
||||||
filename=os.path.join(USER_DIR, "only.log"),
|
|
||||||
level=logging.INFO,
|
|
||||||
datefmt="%Y-%m-%d %H:%M:%S",
|
|
||||||
format="%(asctime)s %(levelname)s %(name)s %(threadName)s : %(message)s",
|
|
||||||
encoding="utf-8",
|
|
||||||
)
|
|
|
@ -1,35 +0,0 @@
|
||||||
"""
|
|
||||||
Gunicorn configuration file
|
|
||||||
"""
|
|
||||||
from gunicorn.app.base import Application
|
|
||||||
from gunicorn import util
|
|
||||||
|
|
||||||
|
|
||||||
class OnlyLegs(Application):
|
|
||||||
"""
|
|
||||||
Gunicorn application
|
|
||||||
"""
|
|
||||||
|
|
||||||
# TODO: Make this not shit, thanks
|
|
||||||
def __init__(self, options={}): # skipcq: PYL-W0231 # pylint: disable=W0231
|
|
||||||
self.usage = None
|
|
||||||
self.callable = None
|
|
||||||
self.options = options
|
|
||||||
self.do_load_config()
|
|
||||||
|
|
||||||
def init(self, *args):
|
|
||||||
"""
|
|
||||||
Initialize the application
|
|
||||||
"""
|
|
||||||
cfg = {}
|
|
||||||
for setting, value in self.options.items():
|
|
||||||
if setting.lower() in self.cfg.settings and value is not None:
|
|
||||||
cfg[setting.lower()] = value
|
|
||||||
return cfg
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def prog(): # skipcq: PYL-E0202 # pylint: disable=E0202, C0116
|
|
||||||
return "OnlyLegs"
|
|
||||||
|
|
||||||
def load(self):
|
|
||||||
return util.import_app("onlylegs.app:app")
|
|
Loading…
Reference in a new issue