mirror of
https://github.com/Derpy-Leggies/OnlyLegs.git
synced 2025-01-16 03:25:21 +00:00
Move prechecks to run file
Add Verbose option Cleanup run file
This commit is contained in:
parent
800ba38241
commit
2eec988815
|
@ -16,28 +16,13 @@ from flask import Flask, render_template
|
|||
# Configuration
|
||||
from dotenv import load_dotenv
|
||||
import platformdirs
|
||||
import yaml
|
||||
from yaml import FullLoader, load
|
||||
|
||||
from . import theme_manager
|
||||
from . import setup
|
||||
|
||||
|
||||
# Run setup checks
|
||||
setup.SetupApp()
|
||||
|
||||
USER_DIR = platformdirs.user_config_dir('onlylegs')
|
||||
|
||||
# Get environment variables
|
||||
load_dotenv(os.path.join(USER_DIR, '.env'))
|
||||
print("Loaded environment variables")
|
||||
|
||||
# Get config file
|
||||
with open(os.path.join(USER_DIR, 'conf.yml'), encoding='utf-8') as f:
|
||||
conf = yaml.load(f, Loader=yaml.FullLoader)
|
||||
print("Loaded gallery config")
|
||||
|
||||
|
||||
def create_app(test_config=None):
|
||||
def create_app(test_config=None, verbose=False):
|
||||
"""
|
||||
Create and configure the main app
|
||||
"""
|
||||
|
@ -45,6 +30,17 @@ def create_app(test_config=None):
|
|||
assets = Environment()
|
||||
cache = Cache(config={'CACHE_TYPE': 'SimpleCache', 'CACHE_DEFAULT_TIMEOUT': 300})
|
||||
compress = Compress()
|
||||
|
||||
# Get environment variables
|
||||
load_dotenv(os.path.join(USER_DIR, '.env'))
|
||||
if verbose:
|
||||
print("Loaded environment variables")
|
||||
|
||||
# Get config file
|
||||
with open(os.path.join(USER_DIR, 'conf.yml'), encoding='utf-8') as f:
|
||||
conf = load(f, Loader=FullLoader)
|
||||
if verbose:
|
||||
print("Loaded gallery config")
|
||||
|
||||
# App configuration
|
||||
app.config.from_mapping(
|
||||
|
@ -67,7 +63,9 @@ def create_app(test_config=None):
|
|||
pass
|
||||
|
||||
# Load theme
|
||||
theme_manager.CompileTheme('default', app.root_path)
|
||||
from . import theme_manager
|
||||
theme_manager.CompileTheme('default', app.root_path, verbose)
|
||||
|
||||
# Bundle JS files
|
||||
js = Bundle('js/*.js', output='gen/packed.js')
|
||||
assets.register('js_all', js)
|
||||
|
|
|
@ -5,13 +5,16 @@ import os
|
|||
import platformdirs
|
||||
|
||||
from sqlalchemy import create_engine, Column, Integer, String, Boolean, DateTime, ForeignKey, PickleType
|
||||
from sqlalchemy.orm import declarative_base, relationship, backref, mapped_column
|
||||
from sqlalchemy.orm import declarative_base, relationship
|
||||
|
||||
|
||||
USER_DIR = platformdirs.user_config_dir('onlylegs')
|
||||
DB_PATH = os.path.join(USER_DIR, 'gallery.sqlite')
|
||||
|
||||
|
||||
path_to_db = os.path.join(platformdirs.user_config_dir('onlylegs'), 'gallery.sqlite')
|
||||
engine = create_engine(f'sqlite:///{path_to_db}', echo=False)
|
||||
# engine = create_engine('postgresql://username:password@host:port/database_name', echo=False)
|
||||
# engine = create_engine('mysql://username:password@host:port/database_name', echo=False)
|
||||
engine = create_engine(f'sqlite:///{DB_PATH}', echo=False)
|
||||
base = declarative_base()
|
||||
|
||||
|
||||
|
@ -130,4 +133,6 @@ class Bans (base): # pylint: disable=too-few-public-methods, C0103
|
|||
created_at = Column(DateTime, nullable=False)
|
||||
|
||||
|
||||
base.metadata.create_all(engine)
|
||||
# check if database file exists, if not create it
|
||||
if not os.path.isfile(DB_PATH):
|
||||
base.metadata.create_all(engine)
|
|
@ -28,7 +28,7 @@
|
|||
</div>
|
||||
{% else %}
|
||||
<div class="big-text">
|
||||
<h1>No image!</h1>
|
||||
<h1>No images</h1>
|
||||
{% if g.user %}
|
||||
<p>You can get started by uploading an image!</p>
|
||||
{% else %}
|
||||
|
|
|
@ -12,13 +12,14 @@ class CompileTheme:
|
|||
"""
|
||||
Compiles the theme into the static folder
|
||||
"""
|
||||
def __init__(self, theme_name, app_path):
|
||||
def __init__(self, theme_name, app_path, verbose=False):
|
||||
"""
|
||||
Initialize the theme manager
|
||||
Compiles the theme into the static folder and loads the fonts
|
||||
"""
|
||||
|
||||
print(f"Loading '{theme_name}' theme...")
|
||||
if verbose:
|
||||
print(f"Loading '{theme_name}' theme...")
|
||||
|
||||
theme_path = os.path.join(app_path, 'themes', theme_name)
|
||||
theme_dest = os.path.join(app_path, 'static', 'theme')
|
||||
|
@ -30,11 +31,11 @@ class CompileTheme:
|
|||
self.load_sass(theme_path, theme_dest)
|
||||
self.load_fonts(theme_path, theme_dest)
|
||||
|
||||
now = datetime.now()
|
||||
print(f"{now.hour}:{now.minute}:{now.second} - Done!\n")
|
||||
if verbose:
|
||||
print(f"{datetime.now().hour}:{datetime.now().minute}:{datetime.now().second} - Done!\n")
|
||||
|
||||
@staticmethod
|
||||
def load_sass(source_path, css_dest):
|
||||
def load_sass(source_path, css_dest, verbose=False):
|
||||
"""
|
||||
Compile the sass (or scss) file into css and save it to the static folder
|
||||
"""
|
||||
|
@ -56,10 +57,11 @@ class CompileTheme:
|
|||
print("Failed to compile!\n", err)
|
||||
sys.exit(1)
|
||||
|
||||
print("Compiled successfully!")
|
||||
if verbose:
|
||||
print("Compiled successfully!")
|
||||
|
||||
@staticmethod
|
||||
def load_fonts(source_path, font_dest):
|
||||
def load_fonts(source_path, font_dest, verbose=False):
|
||||
"""
|
||||
Copy the fonts folder to the static folder
|
||||
"""
|
||||
|
@ -68,7 +70,6 @@ class CompileTheme:
|
|||
font_dest = os.path.join(font_dest, 'fonts')
|
||||
|
||||
if os.path.exists(font_dest):
|
||||
print("Updating fonts...")
|
||||
try:
|
||||
shutil.rmtree(font_dest)
|
||||
except Exception as err:
|
||||
|
@ -77,7 +78,9 @@ class CompileTheme:
|
|||
|
||||
try:
|
||||
shutil.copytree(source_path, font_dest)
|
||||
print("Copied new fonts!")
|
||||
except Exception as err:
|
||||
print("Failed to copy fonts!\n", err)
|
||||
sys.exit(1)
|
||||
|
||||
if verbose:
|
||||
print("Fonts copied successfully!")
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[tool.poetry]
|
||||
name = "onlylegs"
|
||||
version = "23.03.11"
|
||||
version = "23.03.12"
|
||||
description = "Gallery built for fast and simple image management"
|
||||
authors = ["Fluffy-Bean <michal-gdula@protonmail.com>"]
|
||||
license = "MIT"
|
||||
|
|
34
run.py
34
run.py
|
@ -5,28 +5,20 @@ print("""
|
|||
| |_| | | | | | |_| | |__| __/ (_| \__ \
|
||||
\___/|_| |_|_|\__, |_____\___|\__, |___/
|
||||
|___/ |___/
|
||||
Created by Fluffy Bean - Version 23.03.11
|
||||
Created by Fluffy Bean - Version 23.03.12
|
||||
""")
|
||||
|
||||
|
||||
import argparse
|
||||
from setup.args import PORT, ADDRESS, WORKERS, DEBUG, VERBOSE
|
||||
from setup.configuration import Configuration
|
||||
|
||||
|
||||
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='0.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', type=bool, default=False, help='Run as Flask app in debug mode')
|
||||
args = parser.parse_args()
|
||||
|
||||
PORT = args.port
|
||||
ADDRESS = args.address
|
||||
WORKERS = args.workers
|
||||
# Run prechecks
|
||||
Configuration(verbose=VERBOSE)
|
||||
|
||||
|
||||
if args.debug:
|
||||
if DEBUG:
|
||||
from gallery import create_app
|
||||
create_app().run(host=ADDRESS, port=PORT, debug=True)
|
||||
create_app(verbose=VERBOSE).run(host=ADDRESS, port=PORT, debug=True, threaded=True)
|
||||
else:
|
||||
from gunicorn.app.base import Application
|
||||
from gunicorn import util
|
||||
|
@ -49,8 +41,12 @@ else:
|
|||
return 'OnlyLegs'
|
||||
|
||||
def load(self):
|
||||
return util.import_app('gallery:create_app()')
|
||||
return util.import_app(f'gallery:create_app(verbose={VERBOSE})')
|
||||
|
||||
options = {
|
||||
'bind': f'{ADDRESS}:{PORT}',
|
||||
'workers': WORKERS,
|
||||
}
|
||||
|
||||
OnlyLegs(options).run()
|
||||
|
||||
OnlyLegs({'bind': f'{ADDRESS}:{PORT}', 'workers': WORKERS}).run()
|
||||
|
||||
# uwu
|
||||
|
|
30
setup/args.py
Normal file
30
setup/args.py
Normal file
|
@ -0,0 +1,30 @@
|
|||
"""
|
||||
Startup arguments for the OnlyLegs gallery
|
||||
|
||||
-p, --port: Port to run on (default: 5000)
|
||||
-a, --address: Address to run on (default:0.0.0.0)
|
||||
-w, --workers: Number of workers to run (default: 4)
|
||||
|
||||
-d, --debug: Run as Flask app in debug mode (default: False)
|
||||
-V, --verbose: 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='0.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')
|
||||
parser.add_argument('-V', '--verbose', action='store_true', help='Show verbose output')
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
PORT = args.port
|
||||
ADDRESS = args.address
|
||||
WORKERS = args.workers
|
||||
|
||||
DEBUG = args.debug
|
||||
VERBOSE = args.verbose
|
|
@ -7,36 +7,37 @@ import sys
|
|||
import platformdirs
|
||||
import logging
|
||||
import yaml
|
||||
import re
|
||||
|
||||
|
||||
USER_DIR = platformdirs.user_config_dir('onlylegs')
|
||||
|
||||
|
||||
class SetupApp:
|
||||
class Configuration:
|
||||
"""
|
||||
Setup the application on first run
|
||||
"""
|
||||
def __init__(self):
|
||||
def __init__(self, verbose=False):
|
||||
"""
|
||||
Main setup function
|
||||
"""
|
||||
print("Running setup...")
|
||||
if verbose:
|
||||
print("Running startup checks...")
|
||||
|
||||
self.requires_restart = False
|
||||
|
||||
# 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()
|
||||
|
||||
self.logging_config()
|
||||
|
||||
if self.requires_restart:
|
||||
print("WARNING: You need to restart and edit the config files before running the app again!")
|
||||
print("You can find the config files at:", USER_DIR)
|
||||
sys.exit()
|
||||
# Load the config files
|
||||
self.logging_config()
|
||||
|
||||
@staticmethod
|
||||
def make_dir():
|
||||
|
@ -46,11 +47,11 @@ class SetupApp:
|
|||
try:
|
||||
os.makedirs(USER_DIR)
|
||||
os.makedirs(os.path.join(USER_DIR, 'instance'))
|
||||
|
||||
print("Created user directory at:", USER_DIR)
|
||||
except Exception as err:
|
||||
print("Error creating user directory:", err)
|
||||
sys.exit(1)
|
||||
|
||||
print("Created user directory at:", USER_DIR)
|
||||
|
||||
@staticmethod
|
||||
def make_env():
|
||||
|
@ -58,55 +59,93 @@ class SetupApp:
|
|||
Create the .env file with default values
|
||||
"""
|
||||
env_conf = {
|
||||
'FLASK_SECRET': 'dev',
|
||||
'FLASK_SECRET': os.urandom(32).hex(),
|
||||
}
|
||||
|
||||
try:
|
||||
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("Created environment variables")
|
||||
except Exception as err:
|
||||
print("Error creating environment variables:", err)
|
||||
sys.exit(1)
|
||||
|
||||
print("Generated default .env file, please edit!")
|
||||
|
||||
print("""
|
||||
####################################################
|
||||
# PLEASE NOTE DOWN THE FLASK_SECRET KEY LOCARED IN #
|
||||
# YOUR .config/onlylegs/.env FILE! A NEW KEY WAS #
|
||||
# GENERATED FOR YOU! #
|
||||
####################################################
|
||||
""")
|
||||
|
||||
@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("No config file found, please enter the following information:")
|
||||
while not is_correct:
|
||||
try:
|
||||
username = input("Admin username: ")
|
||||
name = input("Admin name: ")
|
||||
email = input("Admin email: ")
|
||||
except ValueError:
|
||||
print("Please enter valid values!")
|
||||
|
||||
# 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
|
||||
_ = input("Is this correct? (y/n): ")
|
||||
|
||||
if _ == 'y' or _ == 'Y':
|
||||
is_correct = True
|
||||
|
||||
yaml_conf = {
|
||||
'admin': {
|
||||
'name': 'Real Person',
|
||||
'username': 'User',
|
||||
'email': 'real-email@some.place'
|
||||
'name': '%s' % name,
|
||||
'username': '%s' % username,
|
||||
'email': '%s' % email,
|
||||
},
|
||||
'upload': {
|
||||
'allowed-extensions': {
|
||||
'jpg': 'jpeg',
|
||||
'jpeg': 'jpeg',
|
||||
'png': 'png',
|
||||
'webp': 'webp'
|
||||
'webp': 'webp',
|
||||
},
|
||||
'max-size': 69,
|
||||
'rename': 'GWA_\{\{username\}\}_\{\{time\}\}'
|
||||
'rename': 'GWA_{{username}}_{{time}}',
|
||||
},
|
||||
'website': {
|
||||
'name': 'OnlyLegs',
|
||||
'motto': 'Gwa Gwa',
|
||||
'language': 'english'
|
||||
'motto': 'A gallery built for fast and simple image management. You can change this in the settings',
|
||||
'language': 'en',
|
||||
}
|
||||
}
|
||||
|
||||
try:
|
||||
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("Created default gallery config")
|
||||
except Exception as err:
|
||||
print("Error creating default gallery config:", err)
|
||||
sys.exit(1)
|
||||
|
||||
print("Generated default YAML config, please edit!")
|
||||
print("Generated config file, you can change these values in the settings of the app")
|
||||
|
||||
@staticmethod
|
||||
def logging_config():
|
Loading…
Reference in a new issue