mirror of
https://github.com/Derpy-Leggies/OnlyLegs.git
synced 2025-01-29 01:28:24 +00:00
commit
fd08fbd0c8
|
@ -1,3 +1,7 @@
|
|||
> **IMPORTANT**
|
||||
> This project is maintained irregularly and is still in rapid development.
|
||||
> Things maybe here now, but not again in a few weeks
|
||||
|
||||
<div align="center">
|
||||
<img src=".github/images/OnlyLegs.png" width="200" height="200"/>
|
||||
<div id="user-content-toc">
|
||||
|
|
|
@ -3,7 +3,6 @@ Onlylegs - API endpoints
|
|||
"""
|
||||
import os
|
||||
import pathlib
|
||||
import re
|
||||
import logging
|
||||
from uuid import uuid4
|
||||
|
||||
|
@ -23,88 +22,13 @@ from flask_login import login_required, current_user
|
|||
from colorthief import ColorThief
|
||||
|
||||
from onlylegs.extensions import db
|
||||
from onlylegs.models import Users, Pictures, Exif
|
||||
from onlylegs.models import Pictures, Exif
|
||||
from onlylegs.utils.generate_image import generate_thumbnail
|
||||
|
||||
|
||||
blueprint = Blueprint("api", __name__, url_prefix="/api")
|
||||
|
||||
|
||||
@blueprint.route("/account/picture/<int:user_id>", methods=["POST"])
|
||||
@login_required
|
||||
def account_picture(user_id):
|
||||
"""
|
||||
Returns the profile of a user
|
||||
"""
|
||||
user = db.get_or_404(Users, user_id)
|
||||
file = request.files.get("file", None)
|
||||
|
||||
# If no image is uploaded, return 404 error
|
||||
if not file:
|
||||
return jsonify({"error": "No file uploaded"}), 400
|
||||
if user.id != current_user.id:
|
||||
return jsonify({"error": "You are not allowed to do this, go away"}), 403
|
||||
|
||||
# Get file extension, generate random name and set file path
|
||||
img_ext = pathlib.Path(file.filename).suffix.replace(".", "").lower()
|
||||
img_name = str(user.id)
|
||||
img_path = os.path.join(current_app.config["PFP_FOLDER"], img_name + "." + img_ext)
|
||||
|
||||
# Check if file extension is allowed
|
||||
if img_ext not in current_app.config["ALLOWED_EXTENSIONS"].keys():
|
||||
logging.info("File extension not allowed: %s", img_ext)
|
||||
return jsonify({"error": "File extension not allowed"}), 403
|
||||
|
||||
if user.picture:
|
||||
# Delete cached files and old image
|
||||
os.remove(os.path.join(current_app.config["PFP_FOLDER"], user.picture))
|
||||
cache_name = user.picture.rsplit(".")[0]
|
||||
for cache_file in pathlib.Path(current_app.config["CACHE_FOLDER"]).glob(
|
||||
cache_name + "*"
|
||||
):
|
||||
os.remove(cache_file)
|
||||
|
||||
# Save file
|
||||
try:
|
||||
file.save(img_path)
|
||||
except OSError as err:
|
||||
logging.info("Error saving file %s because of %s", img_path, err)
|
||||
return jsonify({"error": "Error saving file"}), 500
|
||||
|
||||
img_colors = ColorThief(img_path).get_color()
|
||||
|
||||
# Save to database
|
||||
user.colour = img_colors
|
||||
user.picture = str(img_name + "." + img_ext)
|
||||
db.session.commit()
|
||||
|
||||
return jsonify({"message": "File uploaded"}), 200
|
||||
|
||||
|
||||
@blueprint.route("/account/username/<int:user_id>", methods=["POST"])
|
||||
@login_required
|
||||
def account_username(user_id):
|
||||
"""
|
||||
Returns the profile of a user
|
||||
"""
|
||||
user = db.get_or_404(Users, user_id)
|
||||
new_name = request.form["name"]
|
||||
|
||||
username_regex = re.compile(r"\b[A-Za-z0-9._-]+\b")
|
||||
|
||||
# Validate the form
|
||||
if not new_name or not username_regex.match(new_name):
|
||||
return jsonify({"error": "Username is invalid"}), 400
|
||||
if user.id != current_user.id:
|
||||
return jsonify({"error": "You are not allowed to do this, go away"}), 403
|
||||
|
||||
# Save to database
|
||||
user.username = new_name
|
||||
db.session.commit()
|
||||
|
||||
return jsonify({"message": "Username changed"}), 200
|
||||
|
||||
|
||||
@blueprint.route("/media/<path:path>", methods=["GET"])
|
||||
def media(path):
|
||||
"""
|
||||
|
|
261
onlylegs/app.py
261
onlylegs/app.py
|
@ -1,136 +1,179 @@
|
|||
"""
|
||||
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 logging
|
||||
|
||||
from flask import Flask, render_template, abort, request
|
||||
from werkzeug.security import generate_password_hash
|
||||
from werkzeug.exceptions import HTTPException
|
||||
from flask_assets import Bundle
|
||||
from flask_migrate import init as migrate_init
|
||||
|
||||
from flask import Flask, render_template, abort
|
||||
from werkzeug.exceptions import HTTPException
|
||||
from werkzeug.security import generate_password_hash
|
||||
|
||||
from onlylegs.extensions import db, migrate, login_manager, assets, compress, cache
|
||||
from onlylegs.config import INSTANCE_DIR, MIGRATIONS_DIR
|
||||
from onlylegs.models import Users
|
||||
from onlylegs.views import (
|
||||
index as view_index,
|
||||
image as view_image,
|
||||
group as view_group,
|
||||
settings as view_settings,
|
||||
profile as view_profile,
|
||||
from onlylegs.config import (
|
||||
INSTANCE_DIR,
|
||||
MIGRATIONS_DIR,
|
||||
APPLICATION_ROOT,
|
||||
DATABASE_NAME,
|
||||
)
|
||||
from onlylegs import api
|
||||
from onlylegs import auth as view_auth
|
||||
from onlylegs import filters
|
||||
from onlylegs.models import Users
|
||||
|
||||
from onlylegs.views.index import blueprint as view_index
|
||||
from onlylegs.views.image import blueprint as view_image
|
||||
from onlylegs.views.group import blueprint as view_group
|
||||
from onlylegs.views.settings import blueprint as view_settings
|
||||
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
|
||||
|
||||
|
||||
def set_logger():
|
||||
file_name = os.path.join(APPLICATION_ROOT, "only.log")
|
||||
logging_level = logging.INFO
|
||||
date_format = "%Y-%m-%d %H:%M:%S"
|
||||
log_format = "%(asctime)s %(levelname)s %(name)s %(threadName)s : %(message)s"
|
||||
|
||||
logging.getLogger("werkzeug").disabled = True
|
||||
logging.basicConfig(
|
||||
filename=file_name,
|
||||
level=logging_level,
|
||||
datefmt=date_format,
|
||||
format=log_format,
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
|
||||
def create_db():
|
||||
path_to_database = os.path.join(INSTANCE_DIR, DATABASE_NAME)
|
||||
|
||||
if not os.path.exists(path_to_database):
|
||||
print("Database not found, creating...")
|
||||
|
||||
user = Users(
|
||||
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(user)
|
||||
db.session.commit()
|
||||
migrate_init(directory=MIGRATIONS_DIR)
|
||||
|
||||
print(
|
||||
"####################################################",
|
||||
"# DEFAULT ADMIN USER GENERATED WITH GIVEN USERNAME #",
|
||||
'# THE DEFAULT PASSWORD "changeme!" HAS BEEN USED, #',
|
||||
"# PLEASE RESET IT IN THE SETTINGS! #",
|
||||
"####################################################",
|
||||
sep="\n",
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
print("Database found, continuing...")
|
||||
|
||||
|
||||
def set_login_manager():
|
||||
"""
|
||||
LOGIN MANAGER
|
||||
can also set session_protection to "strong"
|
||||
this would protect against session hijacking
|
||||
"""
|
||||
login_manager.init_app(app)
|
||||
login_manager.login_view = "onlylegs.index"
|
||||
|
||||
@login_manager.user_loader
|
||||
def load_user(user_id):
|
||||
return Users.query.filter_by(alt_id=user_id).first()
|
||||
|
||||
@login_manager.unauthorized_handler
|
||||
def unauthorized():
|
||||
error = 401
|
||||
msg = "You are not authorized to view this page!!!!"
|
||||
return render_template("error.html", error=error, msg=msg), error
|
||||
|
||||
|
||||
def page_assets():
|
||||
"""
|
||||
ASSETS
|
||||
bundles all the sass and js and minifies them
|
||||
"""
|
||||
assets.init_app(app)
|
||||
|
||||
page_scripts = Bundle(
|
||||
"js/*.js", filters="jsmin", output="gen/main.js", depends="js/*.js"
|
||||
)
|
||||
page_styling = Bundle(
|
||||
"sass/style.sass",
|
||||
filters="libsass, cssmin",
|
||||
output="gen/styles.css",
|
||||
depends="sass/**/*.sass",
|
||||
)
|
||||
|
||||
assets.register("scripts", page_scripts)
|
||||
assets.register("styles", page_styling)
|
||||
|
||||
|
||||
def handle_errors():
|
||||
"""
|
||||
ERROR HANDLER
|
||||
handles all the errors and returns a nice error page
|
||||
Code errors are displayed as 500 errors so no
|
||||
sensitive information is leaked
|
||||
"""
|
||||
|
||||
@app.errorhandler(Exception)
|
||||
def error_page(err):
|
||||
if not isinstance(err, HTTPException):
|
||||
abort(500)
|
||||
|
||||
if request.method == "GET":
|
||||
return (
|
||||
render_template("error.html", error=err.code, msg=err.description),
|
||||
err.code,
|
||||
)
|
||||
else:
|
||||
return str(err.code) + ": " + err.description, err.code
|
||||
|
||||
|
||||
def register_blueprints():
|
||||
"""
|
||||
BLUEPRINTS
|
||||
registers all the blueprints
|
||||
"""
|
||||
app.register_blueprint(view_auth)
|
||||
app.register_blueprint(view_index)
|
||||
app.register_blueprint(view_image)
|
||||
app.register_blueprint(view_group)
|
||||
app.register_blueprint(view_profile)
|
||||
app.register_blueprint(view_settings)
|
||||
app.register_blueprint(api)
|
||||
app.register_blueprint(filters)
|
||||
|
||||
|
||||
app = Flask(__name__, instance_path=INSTANCE_DIR)
|
||||
app.config.from_pyfile("config.py")
|
||||
|
||||
# DATABASE
|
||||
db.init_app(app)
|
||||
migrate.init_app(app, db, directory=MIGRATIONS_DIR)
|
||||
|
||||
# If database file doesn't exist, create it
|
||||
if not os.path.exists(os.path.join(INSTANCE_DIR, "gallery.sqlite3")):
|
||||
print("Creating database")
|
||||
with app.app_context():
|
||||
db.create_all()
|
||||
create_db()
|
||||
|
||||
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()
|
||||
set_logger()
|
||||
set_login_manager()
|
||||
page_assets()
|
||||
handle_errors()
|
||||
register_blueprints()
|
||||
|
||||
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
|
||||
# can also set session_protection to "strong"
|
||||
# this would protect against session hijacking
|
||||
login_manager.init_app(app)
|
||||
login_manager.login_view = "onlylegs.index"
|
||||
|
||||
|
||||
@login_manager.user_loader
|
||||
def load_user(user_id):
|
||||
return Users.query.filter_by(alt_id=user_id).first()
|
||||
|
||||
|
||||
@login_manager.unauthorized_handler
|
||||
def unauthorized():
|
||||
error = 401
|
||||
msg = "You are not authorized to view this page!!!!"
|
||||
return render_template("error.html", error=error, msg=msg), error
|
||||
|
||||
|
||||
# ERROR HANDLERS
|
||||
@app.errorhandler(Exception)
|
||||
def error_page(err):
|
||||
"""
|
||||
Error handlers, if the error is not a HTTP error, return 500
|
||||
"""
|
||||
if not isinstance(err, HTTPException):
|
||||
abort(500)
|
||||
return (
|
||||
render_template("error.html", error=err.code, msg=err.description),
|
||||
err.code,
|
||||
)
|
||||
|
||||
|
||||
# ASSETS
|
||||
assets.init_app(app)
|
||||
|
||||
scripts = Bundle(
|
||||
"js/*.js", output="gen/js.js", depends="js/*.js"
|
||||
) # filter jsmin is broken :c
|
||||
styles = Bundle(
|
||||
"sass/style.sass",
|
||||
filters="libsass, cssmin",
|
||||
output="gen/styles.css",
|
||||
depends="sass/**/*.sass",
|
||||
)
|
||||
|
||||
assets.register("scripts", scripts)
|
||||
assets.register("styles", styles)
|
||||
|
||||
# BLUEPRINTS
|
||||
app.register_blueprint(view_auth.blueprint)
|
||||
app.register_blueprint(view_index.blueprint)
|
||||
app.register_blueprint(view_image.blueprint)
|
||||
app.register_blueprint(view_group.blueprint)
|
||||
app.register_blueprint(view_profile.blueprint)
|
||||
app.register_blueprint(view_settings.blueprint)
|
||||
|
||||
app.register_blueprint(api.blueprint)
|
||||
|
||||
# FILTERS
|
||||
app.register_blueprint(filters.blueprint)
|
||||
|
||||
# CACHE AND COMPRESS
|
||||
cache.init_app(app)
|
||||
compress.init_app(app)
|
||||
|
||||
# Yupee! We got there :3
|
||||
print("Done!")
|
||||
logging.info("Gallery started successfully!")
|
||||
|
||||
|
||||
|
|
|
@ -105,5 +105,5 @@ def logout():
|
|||
Clear the current session, including the stored user id
|
||||
"""
|
||||
logout_user()
|
||||
flash(["Goodbye!!!", "4"])
|
||||
flash("Goodbye!!!", "4")
|
||||
return redirect(url_for("gallery.index"))
|
||||
|
|
|
@ -6,42 +6,43 @@ import platformdirs
|
|||
import importlib.metadata
|
||||
from dotenv import load_dotenv
|
||||
from yaml import safe_load
|
||||
from utils import startup
|
||||
|
||||
|
||||
# App Sanity Checks
|
||||
startup.check_dirs()
|
||||
startup.check_env()
|
||||
startup.check_conf()
|
||||
|
||||
|
||||
# Set dirs
|
||||
user_dir = platformdirs.user_config_dir("onlylegs")
|
||||
instance_dir = os.path.join(user_dir, "instance")
|
||||
APPLICATION_ROOT = platformdirs.user_config_dir("onlylegs")
|
||||
UPLOAD_FOLDER = os.path.join(APPLICATION_ROOT, "media", "uploads")
|
||||
MEDIA_FOLDER = os.path.join(APPLICATION_ROOT, "media")
|
||||
CACHE_FOLDER = os.path.join(APPLICATION_ROOT, "media", "cache")
|
||||
PFP_FOLDER = os.path.join(APPLICATION_ROOT, "media", "pfp")
|
||||
BANNER_FOLDER = os.path.join(APPLICATION_ROOT, "media", "banner")
|
||||
|
||||
# Load environment variables
|
||||
# print("Loading environment variables...")
|
||||
load_dotenv(os.path.join(user_dir, ".env"))
|
||||
# Load env and config files
|
||||
load_dotenv(os.path.join(APPLICATION_ROOT, ".env"))
|
||||
|
||||
# Load config from user dir
|
||||
# print("Loading config...")
|
||||
with open(os.path.join(user_dir, "conf.yml"), encoding="utf-8", mode="r") as file:
|
||||
config_file = os.path.join(APPLICATION_ROOT, "conf.yml")
|
||||
with open(config_file, encoding="utf-8", mode="r") as file:
|
||||
conf = safe_load(file)
|
||||
|
||||
|
||||
# Flask config
|
||||
SECRET_KEY = os.environ.get("FLASK_SECRET")
|
||||
SQLALCHEMY_DATABASE_URI = "sqlite:///gallery.sqlite3"
|
||||
MAX_CONTENT_LENGTH = 1024 * 1024 * conf["upload"]["max-size"]
|
||||
ALLOWED_EXTENSIONS = conf["upload"]["allowed-extensions"]
|
||||
APP_VERSION = importlib.metadata.version("OnlyLegs")
|
||||
|
||||
# Database
|
||||
DATABASE_NAME = "gallery.sqlite3"
|
||||
SQLALCHEMY_DATABASE_URI = "sqlite:///" + DATABASE_NAME
|
||||
INSTANCE_DIR = os.path.join(APPLICATION_ROOT, "instance")
|
||||
MIGRATIONS_DIR = os.path.join(INSTANCE_DIR, "migrations")
|
||||
|
||||
# Pass YAML config to app
|
||||
ADMIN_CONF = conf["admin"]
|
||||
UPLOAD_CONF = conf["upload"]
|
||||
WEBSITE_CONF = conf["website"]
|
||||
|
||||
# Directories
|
||||
UPLOAD_FOLDER = os.path.join(user_dir, "media", "uploads")
|
||||
CACHE_FOLDER = os.path.join(user_dir, "media", "cache")
|
||||
PFP_FOLDER = os.path.join(user_dir, "media", "pfp")
|
||||
MEDIA_FOLDER = os.path.join(user_dir, "media")
|
||||
|
||||
# Database
|
||||
INSTANCE_DIR = instance_dir
|
||||
MIGRATIONS_DIR = os.path.join(INSTANCE_DIR, "migrations")
|
||||
|
||||
# App
|
||||
APP_VERSION = importlib.metadata.version("OnlyLegs")
|
||||
|
|
|
@ -4,6 +4,7 @@ Custom Jinja2 filters
|
|||
"""
|
||||
from flask import Blueprint
|
||||
from onlylegs.utils import colour as colour_utils
|
||||
import colorsys
|
||||
|
||||
|
||||
blueprint = Blueprint("filters", __name__)
|
||||
|
@ -17,4 +18,32 @@ def colour_contrast(colour):
|
|||
"color: var(--fg-white);" or "color: var(--fg-black);"
|
||||
"""
|
||||
colour_obj = colour_utils.Colour(colour)
|
||||
return "rgb(var(--fg-black));" if colour_obj.is_light() else "rgb(var(--fg-white));"
|
||||
return (
|
||||
"var(--foreground-black);"
|
||||
if colour_obj.is_light()
|
||||
else "var(--foreground-white);"
|
||||
)
|
||||
|
||||
|
||||
@blueprint.app_template_filter()
|
||||
def hsl_hue(rgb):
|
||||
"""
|
||||
Pass in a rgb value and will return the hue value
|
||||
"""
|
||||
r, g, b = rgb
|
||||
r /= 255
|
||||
g /= 255
|
||||
b /= 255
|
||||
return colorsys.rgb_to_hls(r, g, b)[0] * 360
|
||||
|
||||
|
||||
@blueprint.app_template_filter()
|
||||
def hsl_saturation(rgb):
|
||||
"""
|
||||
Pass in a rgb value and will return the saturation value
|
||||
"""
|
||||
r, g, b = rgb
|
||||
r /= 255
|
||||
g /= 255
|
||||
b /= 255
|
||||
return colorsys.rgb_to_hls(r, g, b)[1] * 100
|
||||
|
|
|
@ -64,7 +64,7 @@ class Exif(db.Model):
|
|||
picture_id = db.Column(db.Integer, db.ForeignKey("pictures.id"))
|
||||
|
||||
key = db.Column(db.String, nullable=False)
|
||||
value = db.Column(db.String, nullable=False)
|
||||
value = db.Column(db.PickleType, nullable=False)
|
||||
|
||||
|
||||
class Albums(db.Model):
|
||||
|
|
|
@ -14,47 +14,6 @@ function imageFullscreen() {
|
|||
}
|
||||
|
||||
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, [
|
||||
{
|
||||
'value': 'Edit',
|
||||
|
@ -62,7 +21,8 @@ function imageShowOptionsPopup(obj) {
|
|||
dissmissContextMenu();
|
||||
imageEditPopup();
|
||||
},
|
||||
'type': 'critical'
|
||||
'type': 'critical',
|
||||
'icon': '<i class="ph-fill ph-pencil"></i>'
|
||||
},
|
||||
{
|
||||
'value': 'Delete',
|
||||
|
@ -70,7 +30,8 @@ function imageShowOptionsPopup(obj) {
|
|||
dissmissContextMenu();
|
||||
imageDeletePopup();
|
||||
},
|
||||
'type': 'critical'
|
||||
'type': 'critical',
|
||||
'icon': '<i class="ph-fill ph-trash"></i>'
|
||||
}
|
||||
], 'button')
|
||||
}
|
||||
|
|
|
@ -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', () => {
|
||||
// Function to upload images
|
||||
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 uploadForm = uploadTab.querySelector('#uploadForm');
|
||||
// let jobList = document.querySelector(".upload-jobs");
|
||||
|
||||
const fileDrop = uploadForm.querySelector('.fileDrop-block');
|
||||
const fileDropTitle = fileDrop.querySelector('.status');
|
||||
|
@ -228,54 +201,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
formData.append("description", fileDescription.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', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
.banner-small
|
||||
width: 100%
|
||||
position: relative
|
||||
color: RGB($fg-white)
|
||||
color: var(--foreground-white)
|
||||
|
||||
.link
|
||||
padding: 0.1rem 0.3rem
|
||||
|
@ -10,15 +10,15 @@
|
|||
text-decoration: none
|
||||
font-weight: 500
|
||||
|
||||
background-color: RGB($fg-white)
|
||||
color: RGB($fg-black)
|
||||
border-radius: $rad-inner
|
||||
background-color: var(--foreground-white)
|
||||
color: var(--foreground-black)
|
||||
border-radius: calc(var(--radius) / 2)
|
||||
|
||||
cursor: pointer
|
||||
|
||||
&:hover
|
||||
background-color: RGB($fg-black)
|
||||
color: RGB($fg-white)
|
||||
background-color: var(--foreground-black)
|
||||
color: var(--foreground-white)
|
||||
|
||||
.banner
|
||||
height: 30rem
|
||||
|
@ -26,7 +26,8 @@
|
|||
|
||||
img
|
||||
position: absolute
|
||||
inset: 0
|
||||
top: 0
|
||||
left: 0
|
||||
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
@ -43,7 +44,7 @@
|
|||
width: 100%
|
||||
height: 100%
|
||||
|
||||
background: linear-gradient(to right, RGB($bg-100), transparent)
|
||||
background: linear-gradient(to right, var(--background-100), transparent 80%, var(--background-100) 100%)
|
||||
|
||||
z-index: +1
|
||||
|
||||
|
@ -79,7 +80,7 @@
|
|||
font-size: 6.9rem
|
||||
font-weight: 700
|
||||
|
||||
color: RGB($primary)
|
||||
color: var(--primary)
|
||||
|
||||
.banner-info
|
||||
grid-area: info
|
||||
|
@ -104,8 +105,8 @@
|
|||
width: 6.9rem
|
||||
height: 6.9rem
|
||||
|
||||
background-color: RGB($primary)
|
||||
border-radius: $rad
|
||||
background-color: var(--primary)
|
||||
border-radius: var(--rad)
|
||||
overflow: hidden
|
||||
|
||||
.banner-small
|
||||
|
@ -144,7 +145,7 @@
|
|||
font-weight: 700
|
||||
font-size: 1.5rem
|
||||
|
||||
color: RGB($primary)
|
||||
color: var(--primary)
|
||||
|
||||
.banner-info
|
||||
margin-right: 0.6rem
|
||||
|
@ -156,7 +157,7 @@
|
|||
margin-left: auto
|
||||
width: auto
|
||||
|
||||
@media (max-width: $breakpoint)
|
||||
@media (max-width: 800px)
|
||||
.banner,
|
||||
.banner-small
|
||||
&::after
|
||||
|
@ -168,7 +169,7 @@
|
|||
max-height: 30vh
|
||||
|
||||
.banner-filter
|
||||
background: linear-gradient(to bottom, RGB($bg-100), transparent)
|
||||
background: linear-gradient(to top, var(--background-100), transparent)
|
||||
|
||||
.banner-content
|
||||
padding: 0.5rem
|
||||
|
@ -192,7 +193,7 @@
|
|||
display: none
|
||||
|
||||
.pill-row
|
||||
margin-top: 0rem
|
||||
margin-top: 0
|
||||
|
||||
.banner-picture
|
||||
margin: 0 auto
|
||||
|
|
|
@ -1,14 +1,3 @@
|
|||
@mixin btn-block($color)
|
||||
background-color: RGBA($color, 0.1)
|
||||
color: RGB($color)
|
||||
// box-shadow: 0 1px 0 RGBA($black, 0.2), 0 -1px 0 RGBA($white, 0.2)
|
||||
|
||||
&:hover, &:focus-visible
|
||||
background-color: RGBA($color, 0.15)
|
||||
color: RGB($color)
|
||||
// box-shadow: 0 1px 0 RGBA($black, 0.2), 0 -1px 0 RGBA($color, 0.2)
|
||||
|
||||
|
||||
.btn-block
|
||||
padding: 0.4rem 0.7rem
|
||||
|
||||
|
@ -26,19 +15,17 @@
|
|||
font-weight: 400
|
||||
text-align: center
|
||||
|
||||
background-color: RGBA($white, 0.1)
|
||||
color: RGB($white)
|
||||
background-color: var(--white-transparent)
|
||||
color: var(--white)
|
||||
border: none
|
||||
border-radius: $rad-inner
|
||||
// box-shadow: 0 1px 0 RGBA($black, 0.2), 0 -1px 0 RGBA($white, 0.2)
|
||||
border-radius: calc(var(--rad) / 2)
|
||||
outline: none
|
||||
|
||||
cursor: pointer
|
||||
transition: background-color 0.15s ease-in-out, color 0.15s ease-in-out, box-shadow 0.15s ease-in-out
|
||||
|
||||
&:hover, &:focus-visible
|
||||
background-color: RGBA($white, 0.2)
|
||||
// box-shadow: 0 1px 0 RGBA($black, 0.3), 0 -1px 0 RGBA($white, 0.3)
|
||||
background-color: var(--white-transparent)
|
||||
|
||||
&.transparent
|
||||
background-color: transparent
|
||||
|
@ -47,20 +34,50 @@
|
|||
text-decoration: underline
|
||||
|
||||
&.primary
|
||||
@include btn-block($primary)
|
||||
&.critical
|
||||
@include btn-block($critical)
|
||||
&.warning
|
||||
@include btn-block($warning)
|
||||
background-color: var(--primary-transparent)
|
||||
color: var(--primary)
|
||||
|
||||
&:hover, &:focus-visible
|
||||
background-color: var(--primary)
|
||||
color: var(--black)
|
||||
&.success
|
||||
@include btn-block($success)
|
||||
background-color: var(--success-transparent)
|
||||
color: var(--success)
|
||||
|
||||
&:hover, &:focus-visible
|
||||
background-color: var(--success)
|
||||
color: var(--black)
|
||||
&.warning
|
||||
background-color: var(--warning-transparent)
|
||||
color: var(--warning)
|
||||
|
||||
&:hover, &:focus-visible
|
||||
background-color: var(--warning)
|
||||
color: var(--black)
|
||||
&.critical
|
||||
background-color: var(--danger-transparent)
|
||||
color: var(--danger)
|
||||
|
||||
&:hover, &:focus-visible
|
||||
background-color: var(--danger)
|
||||
color: var(--black)
|
||||
&.info
|
||||
@include btn-block($info)
|
||||
background-color: var(--info-transparent)
|
||||
color: var(--info)
|
||||
|
||||
&:hover, &:focus-visible
|
||||
background-color: var(--info)
|
||||
color: var(--black)
|
||||
&.black
|
||||
@include btn-block($black)
|
||||
background-color: var(--black-transparent)
|
||||
color: var(--white)
|
||||
|
||||
&:hover, &:focus-visible
|
||||
background-color: var(--black)
|
||||
color: var(--white)
|
||||
|
||||
&.disabled, &:disabled
|
||||
color: RGB($fg-dim)
|
||||
color: var(--foreground-gray)
|
||||
cursor: unset
|
||||
|
||||
.input-checkbox
|
||||
|
@ -77,7 +94,7 @@
|
|||
font-weight: 400
|
||||
text-align: left
|
||||
|
||||
color: RGB($fg-white)
|
||||
color: var(--foreground-white)
|
||||
|
||||
.input-block
|
||||
padding: 0.4rem 0.7rem
|
||||
|
@ -95,28 +112,32 @@
|
|||
font-weight: 400
|
||||
text-align: left
|
||||
|
||||
background-color: RGBA($white, 0.1)
|
||||
color: RGB($white)
|
||||
background-color: var(--white-transparent)
|
||||
color: var(--white)
|
||||
border: none
|
||||
border-bottom: 3px solid RGBA($white, 0.1)
|
||||
border-radius: $rad-inner
|
||||
// box-shadow: 0 1px 0 RGBA($black, 0.2), 0 -1px 0 RGBA($white, 0.2)
|
||||
border-bottom: 3px solid var(--white-transparent)
|
||||
border-radius: calc(var(--rad) / 2)
|
||||
outline: none
|
||||
|
||||
cursor: pointer
|
||||
transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out
|
||||
|
||||
&:not(:focus):not([value=""]):not(:placeholder-shown)
|
||||
border-color: RGBA($white, 0.3)
|
||||
border-color: var(--white-transparent)
|
||||
|
||||
&:hover
|
||||
border-color: RGBA($white, 0.3)
|
||||
border-color: var(--white-transparent)
|
||||
|
||||
&:focus
|
||||
border-color: RGB($primary)
|
||||
border-color: var(--primary)
|
||||
|
||||
&.black
|
||||
@include btn-block($black)
|
||||
background-color: var(--black-transparent)
|
||||
color: var(--white)
|
||||
|
||||
&:hover, &:focus-visible
|
||||
background-color: var(--black)
|
||||
color: var(--white)
|
||||
|
||||
.fileDrop-block
|
||||
padding: 1rem 1.25rem
|
||||
|
@ -136,11 +157,10 @@
|
|||
font-weight: 400
|
||||
text-align: center
|
||||
|
||||
background-color: RGBA($white, 0.1)
|
||||
color: RGB($white)
|
||||
background-color: var(--white-transparent)
|
||||
color: var(--white)
|
||||
border: none
|
||||
border-radius: $rad-inner
|
||||
// box-shadow: 0 1px 0 RGBA($black, 0.2), 0 -1px 0 RGBA($white, 0.2)
|
||||
border-radius: calc(var(--rad) / 2)
|
||||
outline: none
|
||||
|
||||
cursor: pointer
|
||||
|
@ -164,24 +184,21 @@
|
|||
overflow: hidden
|
||||
|
||||
&:hover, &:focus-visible
|
||||
background-color: RGBA($white, 0.2)
|
||||
color: RGB($white)
|
||||
// box-shadow: 0 1px 0 RGBA($black, 0.3), 0 -1px 0 RGBA($white, 0.3)
|
||||
background-color: var(--white-transparent)
|
||||
color: var(--white)
|
||||
|
||||
&.active
|
||||
background-color: RGBA($primary, 0.2)
|
||||
color: RGB($primary)
|
||||
// box-shadow: 0 1px 0 RGBA($black, 0.3), 0 -1px 0 RGBA($primary, 0.3)
|
||||
background-color: var(--primary-transparent)
|
||||
color: var(--primary)
|
||||
|
||||
&.edging
|
||||
background-color: RGBA($white, 0.2)
|
||||
color: RGB($white)
|
||||
// box-shadow: 0 1px 0 RGBA($black, 0.3), 0 -1px 0 RGBA($white, 0.3)
|
||||
background-color: var(--white-transparent)
|
||||
color: var(--white)
|
||||
|
||||
input
|
||||
display: none // So it doesnt get in the way of the drop as that breaks things
|
||||
// So it doesnt get in the way of the drop as that breaks things
|
||||
display: none
|
||||
|
||||
&.error
|
||||
background-color: RGBA($critical, 0.2)
|
||||
color: RGB($critical)
|
||||
// box-shadow: 0 1px 0 RGBA($black, 0.3), 0 -1px 0 RGBA($critical, 0.3)
|
||||
background-color: var(--danger)
|
||||
color: var(--black)
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
.info-button
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
width: auto
|
||||
height: auto
|
||||
|
||||
position: fixed
|
||||
bottom: 0.75rem
|
||||
right: -3rem
|
||||
|
||||
display: flex
|
||||
justify-content: center
|
||||
align-items: center
|
||||
|
||||
background-color: RGB($bg-300)
|
||||
color: RGB($fg-white)
|
||||
border-radius: $rad
|
||||
border: none
|
||||
opacity: 0
|
||||
|
||||
z-index: 20
|
||||
cursor: pointer
|
||||
transition: all 0.2s cubic-bezier(.86, 0, .07, 1)
|
||||
|
||||
i
|
||||
margin: 0.5rem
|
||||
font-size: 1.25rem
|
||||
|
||||
&:hover
|
||||
color: RGB($info)
|
||||
|
||||
&.show
|
||||
right: 0.75rem
|
||||
opacity: 1
|
||||
|
||||
@media (max-width: $breakpoint)
|
||||
.info-button
|
||||
bottom: 4.25rem
|
|
@ -16,9 +16,8 @@
|
|||
|
||||
display: flex
|
||||
|
||||
background-color: RGB($bg-200)
|
||||
border-radius: $rad
|
||||
// box-shadow: 0 1px 0 RGB($bg-100), 0 -1px 0 RGB($bg-300)
|
||||
background-color: var(--background-200)
|
||||
border-radius: var(--rad)
|
||||
|
||||
.pill-text
|
||||
margin: 0
|
||||
|
@ -37,9 +36,9 @@
|
|||
font-size: 1rem
|
||||
font-weight: 400
|
||||
|
||||
background-color: RGB($bg-200)
|
||||
color: RGB($fg-white)
|
||||
border-radius: $rad
|
||||
background-color: var(--background-200)
|
||||
color: var(--foreground-white)
|
||||
border-radius: var(--rad)
|
||||
|
||||
.pill-item
|
||||
margin: 0
|
||||
|
@ -58,42 +57,41 @@
|
|||
|
||||
border: none
|
||||
background-color: transparent
|
||||
color: RGB($fg-white)
|
||||
color: var(--foreground-white)
|
||||
|
||||
i
|
||||
font-size: 1.25rem
|
||||
|
||||
&:hover
|
||||
cursor: pointer
|
||||
color: var(--primary)
|
||||
|
||||
color: RGB($primary)
|
||||
|
||||
&.disabled, &:disabled
|
||||
color: RGB($fg-dim)
|
||||
cursor: unset
|
||||
&:disabled, &[disabled], &.disabled
|
||||
color: var(--foreground-gray)
|
||||
cursor: default
|
||||
|
||||
.pill__critical
|
||||
color: RGB($critical)
|
||||
color: var(--danger)
|
||||
|
||||
span
|
||||
background: RGB($critical)
|
||||
color: RGB($fg-white)
|
||||
background: var(--danger)
|
||||
color: var(--foreground-white)
|
||||
|
||||
i
|
||||
color: RGB($critical)
|
||||
color: var(--danger)
|
||||
|
||||
&:hover
|
||||
color: RGB($fg-white)
|
||||
color: var(--foreground-white)
|
||||
|
||||
.pill__info
|
||||
color: RGB($info)
|
||||
color: var(--info)
|
||||
|
||||
span
|
||||
color: RGB($info)
|
||||
color: var(--info)
|
||||
|
||||
&:hover
|
||||
color: RGB($fg-white)
|
||||
color: var(--foreground-white)
|
||||
|
||||
@media (max-width: $breakpoint)
|
||||
@media (max-width: var(--breakpoint))
|
||||
.tool-tip
|
||||
display: none
|
|
@ -13,9 +13,9 @@
|
|||
justify-content: center
|
||||
align-items: center
|
||||
|
||||
background-color: RGB($bg-300)
|
||||
color: RGB($fg-white)
|
||||
border-radius: $rad
|
||||
background-color: var(--background-100)
|
||||
color: var(--foreground-white)
|
||||
border-radius: calc(var(--rad) / 2)
|
||||
border: none
|
||||
opacity: 0
|
||||
|
||||
|
@ -28,12 +28,12 @@
|
|||
font-size: 1.25rem
|
||||
|
||||
&:hover
|
||||
color: RGB($primary)
|
||||
color: var(--primary)
|
||||
|
||||
&.show
|
||||
right: 0.75rem
|
||||
opacity: 1
|
||||
|
||||
@media (max-width: $breakpoint)
|
||||
@media (max-width: 800px)
|
||||
.top-of-page
|
||||
bottom: 4.25rem
|
||||
|
|
|
@ -25,13 +25,13 @@
|
|||
align-items: flex-start
|
||||
gap: 0.25rem
|
||||
|
||||
background-color: RGB($bg-300)
|
||||
border: 1px solid RGB($bg-200)
|
||||
background-color: var(--background-300)
|
||||
border: 1px solid var(--background-200)
|
||||
border-radius: 6px
|
||||
|
||||
overflow: hidden
|
||||
|
||||
transition: transform 0.2s ease-in-out, opacity 0.2s ease-in-out
|
||||
transition: transform 0.35s var(--animation-bounce), opacity 0.35s var(--animation-bounce)
|
||||
transform-origin: center center
|
||||
opacity: 0.5
|
||||
transform: scale(0, 0)
|
||||
|
@ -46,7 +46,7 @@
|
|||
text-align: center
|
||||
font-size: 1.2rem
|
||||
font-weight: 400
|
||||
color: RGB($fg-white)
|
||||
color: var(--foreground-white)
|
||||
|
||||
.contextMenuItem
|
||||
margin: 0
|
||||
|
@ -61,22 +61,22 @@
|
|||
align-items: center
|
||||
gap: 0.5rem
|
||||
|
||||
background-color: RGB($bg-300)
|
||||
color: RGB($fg-white)
|
||||
background-color: var(--background-300)
|
||||
color: var(--foreground-white)
|
||||
border: none
|
||||
border-radius: 3px
|
||||
|
||||
cursor: pointer
|
||||
.contextMenuItem:hover
|
||||
background-color: RGB($bg-200)
|
||||
background-color: var(--background-200)
|
||||
.contextMenuItem__critical
|
||||
color: RGB($critical)
|
||||
color: var(--danger)
|
||||
.contextMenuItem__warning
|
||||
color: RGB($warning)
|
||||
color: var(--warning)
|
||||
.contextMenuItem__success
|
||||
color: RGB($success)
|
||||
color: var(--success)
|
||||
.contextMenuItem__info
|
||||
color: RGB($primary)
|
||||
color: var(--primary)
|
||||
|
||||
.contextMenuText
|
||||
margin: 0
|
||||
|
@ -104,7 +104,7 @@
|
|||
height: 1px
|
||||
|
||||
border: none
|
||||
background-color: RGB($bg-200)
|
||||
background-color: var(--background-200)
|
||||
|
||||
.contextMenu__show
|
||||
opacity: 1
|
||||
|
|
|
@ -12,26 +12,21 @@
|
|||
font-weight: 700
|
||||
|
||||
.gallery-grid
|
||||
margin: 0
|
||||
padding: 0.35rem
|
||||
|
||||
width: 100%
|
||||
|
||||
display: grid
|
||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr))
|
||||
gap: 0.5rem
|
||||
|
||||
.gallery-item
|
||||
margin: 0.35rem
|
||||
padding: 0
|
||||
|
||||
position: relative
|
||||
|
||||
border-radius: $rad-inner
|
||||
box-shadow: 0 0.15rem 0.4rem 0.1rem RGBA($bg-100, 0.4)
|
||||
border-radius: calc(var(--rad) / 2)
|
||||
box-shadow: 0 0.15rem 0.4rem 0.1rem var(--black-transparent)
|
||||
|
||||
box-sizing: border-box
|
||||
overflow: hidden
|
||||
transition: box-shadow 0.2s cubic-bezier(.79, .14, .15, .86)
|
||||
transition: box-shadow 0.2s var(--animation-smooth)
|
||||
|
||||
.image-filter
|
||||
margin: 0
|
||||
|
@ -48,11 +43,11 @@
|
|||
flex-direction: column
|
||||
justify-content: flex-end
|
||||
|
||||
background-image: linear-gradient(to top, rgba($bg-100, 0.69), transparent)
|
||||
background-image: linear-gradient(to top, var(--black-transparent), transparent)
|
||||
opacity: 0 // hide
|
||||
|
||||
z-index: +4
|
||||
transition: opacity 0.2s cubic-bezier(.79, .14, .15, .86)
|
||||
transition: opacity 0.2s var(--animation-smooth)
|
||||
|
||||
.image-title,
|
||||
.image-subtitle
|
||||
|
@ -63,8 +58,8 @@
|
|||
text-overflow: ellipsis
|
||||
overflow: hidden
|
||||
|
||||
color: RGB($fg-white)
|
||||
text-shadow: 0px 0px 2px RGB($fg-black)
|
||||
color: var(--foreground-white)
|
||||
text-shadow: 0 0 2px var(--foreground-black)
|
||||
|
||||
.image-title
|
||||
font-size: 0.9rem
|
||||
|
@ -84,21 +79,20 @@
|
|||
object-fit: cover
|
||||
object-position: center
|
||||
|
||||
background-color: RGB($bg-bright)
|
||||
background-color: var(--background-bright)
|
||||
|
||||
&:hover
|
||||
box-shadow: 0 0.2rem 0.4rem 0.1rem RGBA($bg-100, 0.6)
|
||||
box-shadow: 0 0.2rem 0.4rem 0.1rem var(--black-transparent)
|
||||
|
||||
.image-filter
|
||||
opacity: 1
|
||||
|
||||
.group-item
|
||||
margin: 0.35rem
|
||||
padding: 0
|
||||
|
||||
position: relative
|
||||
|
||||
border-radius: $rad-inner
|
||||
border-radius: calc(var(--rad) / 2)
|
||||
|
||||
box-sizing: border-box
|
||||
overflow: hidden
|
||||
|
@ -119,7 +113,7 @@
|
|||
flex-direction: column
|
||||
justify-content: flex-end
|
||||
|
||||
background-image: linear-gradient(to top, rgba($bg-100, 0.8), transparent)
|
||||
background-image: linear-gradient(to top, var(--black-transparent), transparent)
|
||||
|
||||
z-index: +4
|
||||
|
||||
|
@ -132,8 +126,8 @@
|
|||
text-overflow: ellipsis
|
||||
overflow: hidden
|
||||
|
||||
color: RGB($fg-white)
|
||||
text-shadow: 0px 0px 2px RGB($fg-black)
|
||||
color: var(--foreground-white)
|
||||
text-shadow: 0 0 2px var(--foreground-black)
|
||||
|
||||
.image-title
|
||||
font-size: 0.9rem
|
||||
|
@ -165,11 +159,11 @@
|
|||
object-fit: cover
|
||||
object-position: center
|
||||
|
||||
background-color: RGB($bg-bright)
|
||||
border-radius: $rad-inner
|
||||
box-shadow: 0 0 0.4rem 0.25rem RGBA($bg-100, 0.1)
|
||||
background-color: var(--background-800)
|
||||
border-radius: calc(var(--rad) / 2)
|
||||
box-shadow: 0 0 0.4rem 0.25rem var(--black-transparent)
|
||||
|
||||
transition: transform 0.2s cubic-bezier(.79, .14, .15, .86)
|
||||
transition: transform 0.2s var(--animation-smooth)
|
||||
|
||||
&.size-1
|
||||
.data-1
|
||||
|
@ -224,5 +218,5 @@
|
|||
grid-template-columns: auto auto auto
|
||||
|
||||
.gallery-item
|
||||
margin: 0.35rem
|
||||
margin: 0.1rem
|
||||
position: relative
|
|
@ -1,11 +1,11 @@
|
|||
.info-container
|
||||
padding: 0.5rem 0 0 0.5rem
|
||||
padding: 0.5rem 0 0.5rem 0.5rem
|
||||
width: 27rem
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
bottom: 0
|
||||
background-image: linear-gradient(90deg, $bg-transparent, transparent)
|
||||
background-image: linear-gradient(90deg, var(--background-shade), transparent)
|
||||
overflow-y: auto
|
||||
transition: left 0.3s cubic-bezier(0.76, 0, 0.17, 1)
|
||||
z-index: 2
|
||||
|
@ -18,7 +18,7 @@
|
|||
left: -27rem
|
||||
@media (max-width: 1100px)
|
||||
.info-container
|
||||
padding: 0 0.5rem 0 0.5rem
|
||||
padding: 0
|
||||
width: 100%
|
||||
position: relative
|
||||
background: none
|
||||
|
@ -32,9 +32,9 @@ details
|
|||
padding: 0.5rem
|
||||
display: flex
|
||||
flex-direction: column
|
||||
background-color: RGB($bg-300)
|
||||
color: RGB($fg-white)
|
||||
border-radius: $rad
|
||||
background-color: var(--background-300)
|
||||
color: var(--foreground-white)
|
||||
border-radius: var(--rad)
|
||||
overflow: hidden
|
||||
|
||||
summary
|
||||
|
@ -44,7 +44,7 @@ details
|
|||
justify-content: flex-start
|
||||
align-items: center
|
||||
position: relative
|
||||
color: RGB($primary)
|
||||
color: var(--primary)
|
||||
|
||||
> i
|
||||
margin-right: 0
|
||||
|
@ -58,13 +58,6 @@ details
|
|||
font-size: 1.1rem
|
||||
font-weight: 500
|
||||
|
||||
&[open]
|
||||
summary
|
||||
margin-bottom: 0.5rem
|
||||
|
||||
> i.collapse-indicator
|
||||
transform: rotate(90deg)
|
||||
|
||||
p
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
@ -79,7 +72,7 @@ details
|
|||
margin: 0
|
||||
padding: 0
|
||||
|
||||
color: RGB($primary)
|
||||
color: var(--primary)
|
||||
|
||||
cursor: pointer
|
||||
text-decoration: none
|
||||
|
@ -91,7 +84,7 @@ details
|
|||
width: 1.1rem
|
||||
height: 1.1rem
|
||||
|
||||
border-radius: $rad-inner
|
||||
border-radius: calc(var(--rad) / 2)
|
||||
|
||||
object-fit: cover
|
||||
|
||||
|
@ -137,6 +130,16 @@ details
|
|||
tr:last-of-type td
|
||||
padding-bottom: 0
|
||||
|
||||
&[open]
|
||||
summary
|
||||
margin-bottom: 0.5rem
|
||||
|
||||
> i.collapse-indicator
|
||||
transform: rotate(90deg)
|
||||
|
||||
&:last-of-type
|
||||
margin-bottom: 0
|
||||
|
||||
.img-colours
|
||||
width: 100%
|
||||
|
||||
|
@ -154,7 +157,7 @@ details
|
|||
justify-content: center
|
||||
align-items: center
|
||||
|
||||
border-radius: $rad-inner
|
||||
border-radius: calc(var(--rad) / 2)
|
||||
border: none
|
||||
|
||||
i
|
||||
|
@ -197,7 +200,9 @@ details
|
|||
max-height: 100%
|
||||
object-fit: contain
|
||||
object-position: center
|
||||
border-radius: $rad
|
||||
border-radius: var(--rad)
|
||||
|
||||
transition: border-radius 0.3s cubic-bezier(0.76, 0, 0.17, 1)
|
||||
|
||||
&.collapsed
|
||||
padding: 0
|
||||
|
@ -207,6 +212,7 @@ details
|
|||
border-radius: 0
|
||||
@media (max-width: 1100px)
|
||||
.image-container
|
||||
padding: 0 0 0.5rem 0
|
||||
position: relative
|
||||
left: 0
|
||||
|
||||
|
@ -218,17 +224,17 @@ details
|
|||
max-height: 69vh
|
||||
|
||||
&.collapsed
|
||||
padding: 0.5rem
|
||||
padding: 0 0 0.5rem 0
|
||||
left: 0
|
||||
|
||||
picture img
|
||||
border-radius: $rad
|
||||
border-radius: var(--rad)
|
||||
|
||||
.background
|
||||
position: absolute
|
||||
inset: 0
|
||||
background-color: RGB($bg-300)
|
||||
background-image: linear-gradient(to right, RGB($bg-400) 15%, RGB($bg-200) 35%, RGB($bg-400) 50%)
|
||||
background-color: var(--background-300)
|
||||
background-image: linear-gradient(to right, var(--background-400) 15%, var(--background-200) 35%, var(--background-400) 50%)
|
||||
background-size: 1000px 640px
|
||||
animation: imgLoading 1.8s linear infinite forwards
|
||||
user-select: none
|
||||
|
@ -240,7 +246,7 @@ details
|
|||
inset: 0
|
||||
width: 100%
|
||||
height: 100%
|
||||
background-color: RGB($fg-white)
|
||||
background-color: var(--foreground-white)
|
||||
filter: blur(3rem) saturate(1.2) brightness(0.7)
|
||||
transform: scale(1.1)
|
||||
object-fit: cover
|
||||
|
|
|
@ -42,27 +42,27 @@ nav
|
|||
> i
|
||||
padding: 0.5rem
|
||||
font-size: 1.3rem
|
||||
border-radius: $rad-inner
|
||||
border-radius: calc(var(--rad) / 2)
|
||||
color: inherit
|
||||
|
||||
> .nav-pfp
|
||||
padding: 0.4rem
|
||||
width: 2.3rem
|
||||
height: 2.3rem
|
||||
border-radius: $rad-inner
|
||||
border-radius: calc(var(--rad) / 2)
|
||||
|
||||
img
|
||||
width: 100%
|
||||
height: 100%
|
||||
object-fit: cover
|
||||
border-radius: $rad-inner
|
||||
border-radius: calc(var(--rad) / 2)
|
||||
|
||||
&:hover
|
||||
> i, .nav-pfp
|
||||
background: RGBA($fg-white, 0.1)
|
||||
background: var(--white-transparent)
|
||||
|
||||
&.selected
|
||||
color: RGB($primary)
|
||||
color: var(--primary)
|
||||
|
||||
&::before
|
||||
content: ''
|
||||
|
@ -76,9 +76,9 @@ nav
|
|||
height: calc(100% - 1rem)
|
||||
|
||||
background-color: currentColor
|
||||
border-radius: $rad-inner
|
||||
border-radius: calc(var(--rad) / 2)
|
||||
|
||||
@media (max-width: $breakpoint)
|
||||
@media (max-width: 800px)
|
||||
nav
|
||||
width: 100vw
|
||||
height: 3.5rem
|
||||
|
@ -91,7 +91,7 @@ nav
|
|||
bottom: 0
|
||||
left: 0
|
||||
|
||||
background-color: RGB($background)
|
||||
background-color: var(--background-100)
|
||||
|
||||
> span
|
||||
display: none
|
||||
|
|
|
@ -1,23 +1,9 @@
|
|||
@keyframes notificationTimeout
|
||||
0%
|
||||
left: -100%
|
||||
height: 3px
|
||||
90%
|
||||
left: 0%
|
||||
height: 3px
|
||||
95%
|
||||
left: 0%
|
||||
height: 0
|
||||
width: 0
|
||||
100%
|
||||
left: 0%
|
||||
height: 0
|
||||
|
||||
@mixin notification($color)
|
||||
color: RGB($color)
|
||||
width: 100%
|
||||
|
||||
&::after
|
||||
background-color: RGB($color)
|
||||
|
||||
.notifications
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
@ -46,9 +32,9 @@
|
|||
|
||||
position: relative
|
||||
|
||||
background-color: RGB($bg-300)
|
||||
border-radius: $rad-inner
|
||||
color: RGB($fg-white)
|
||||
background-color: var(--background-400)
|
||||
border-radius: calc(var(--rad) / 2)
|
||||
color: var(--foreground-white)
|
||||
opacity: 0
|
||||
transform: scale(0.8)
|
||||
|
||||
|
@ -60,26 +46,34 @@
|
|||
&::after
|
||||
content: ""
|
||||
|
||||
width: 100%
|
||||
width: 0
|
||||
height: 3px
|
||||
|
||||
position: absolute
|
||||
bottom: 0px
|
||||
left: 0px
|
||||
bottom: 0
|
||||
left: 0
|
||||
|
||||
background-color: RGB($fg-white)
|
||||
background-color: var(--foreground-white)
|
||||
|
||||
z-index: +2
|
||||
animation: notificationTimeout 5.1s linear
|
||||
animation: notificationTimeout 5.1s ease-out forwards
|
||||
|
||||
&.success
|
||||
@include notification($success)
|
||||
color: var(--success)
|
||||
&::after
|
||||
background-color: var(--success)
|
||||
&.warning
|
||||
@include notification($warning)
|
||||
color: var(--warning)
|
||||
&::after
|
||||
background-color: var(--warning)
|
||||
&.critical
|
||||
@include notification($critical)
|
||||
color: var(--danger)
|
||||
&::after
|
||||
background-color: var(--danger)
|
||||
&.info
|
||||
@include notification($info)
|
||||
color: var(--info)
|
||||
&::after
|
||||
background-color: var(--info)
|
||||
|
||||
&.show
|
||||
opacity: 1
|
||||
|
@ -89,7 +83,7 @@
|
|||
margin: 0
|
||||
max-height: 0
|
||||
opacity: 0
|
||||
transform: translateX(100%)
|
||||
transform: translateY(1rem)
|
||||
transition: all 0.4s ease-in-out, max-height 0.2s ease-in-out
|
||||
|
||||
.sniffle__notification-icon
|
||||
|
@ -103,7 +97,7 @@
|
|||
justify-content: center
|
||||
align-items: center
|
||||
|
||||
background-color: RGB($bg-200)
|
||||
background-color: var(--background-300)
|
||||
|
||||
i
|
||||
font-size: 1.25rem
|
||||
|
@ -125,7 +119,7 @@
|
|||
line-height: 1
|
||||
text-align: left
|
||||
|
||||
@media (max-width: $breakpoint)
|
||||
@media (max-width: 800px)
|
||||
.notifications
|
||||
bottom: 3.8rem
|
||||
width: calc(100vw - 0.6rem)
|
||||
|
@ -133,10 +127,6 @@
|
|||
|
||||
.sniffle__notification
|
||||
width: 100%
|
||||
|
||||
&.hide
|
||||
opacity: 0
|
||||
transform: translateY(1rem)
|
||||
|
||||
.sniffle__notification-time
|
||||
width: 100%
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
display: none
|
||||
|
||||
background-color: $bg-transparent
|
||||
background-color: var(--background-shade)
|
||||
opacity: 0
|
||||
|
||||
z-index: 101
|
||||
|
@ -38,12 +38,12 @@
|
|||
display: flex
|
||||
flex-direction: column
|
||||
|
||||
background-color: RGB($bg-200)
|
||||
border-radius: $rad
|
||||
background-color: var(--background-400)
|
||||
border-radius: var(--rad)
|
||||
overflow: hidden
|
||||
|
||||
z-index: +2
|
||||
transition: transform 0.2s $animation-smooth
|
||||
transition: transform 0.2s var(--animation-bounce)
|
||||
|
||||
.pop-up-header
|
||||
margin: 0 0 0.5rem 0
|
||||
|
@ -73,7 +73,7 @@
|
|||
font-weight: 700
|
||||
text-align: left
|
||||
|
||||
color: RGB($fg-white)
|
||||
color: var(--foreground-white)
|
||||
|
||||
p
|
||||
margin: 0
|
||||
|
@ -84,7 +84,7 @@
|
|||
font-weight: 400
|
||||
text-align: left
|
||||
|
||||
color: RGB($fg-white)
|
||||
color: var(--foreground-white)
|
||||
|
||||
svg
|
||||
width: 1rem
|
||||
|
@ -94,7 +94,7 @@
|
|||
vertical-align: middle
|
||||
|
||||
a, .link
|
||||
color: RGB($primary)
|
||||
color: var(--primary)
|
||||
|
||||
cursor: pointer
|
||||
text-decoration: none
|
||||
|
@ -127,15 +127,13 @@
|
|||
justify-content: flex-end
|
||||
gap: 0.5rem
|
||||
|
||||
// background-color: RGB($bg-100)
|
||||
|
||||
&.active
|
||||
opacity: 1
|
||||
|
||||
.pop-up-wrapper
|
||||
transform: translate(-50%, 50%) scale(1)
|
||||
|
||||
@media (max-width: $breakpoint)
|
||||
@media (max-width: 800px)
|
||||
.pop-up
|
||||
.pop-up-wrapper
|
||||
max-width: calc(100% - 0.75rem)
|
||||
|
|
|
@ -9,10 +9,10 @@
|
|||
justify-content: center
|
||||
gap: 1rem
|
||||
|
||||
background-color: RGB($bg-400)
|
||||
color: RGB($fg-white)
|
||||
border: 2px solid RGB($bg-200)
|
||||
border-radius: $rad-inner
|
||||
background-color: var(--background-400)
|
||||
color: var(--foreground-white)
|
||||
border: 2px solid var(--background-200)
|
||||
border-radius: calc(var(--rad) / 2)
|
||||
|
||||
h2
|
||||
margin: 0
|
||||
|
|
|
@ -11,10 +11,10 @@
|
|||
font-weight: 500
|
||||
text-decoration: none
|
||||
|
||||
border-radius: $rad-inner
|
||||
border-radius: calc(var(--rad) / 2)
|
||||
border: none
|
||||
background-color: RGBA($primary, 0.1)
|
||||
color: RGB($primary)
|
||||
background-color: var(--primary-transparent)
|
||||
color: var(--primary)
|
||||
|
||||
cursor: pointer
|
||||
transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out
|
||||
|
@ -23,4 +23,4 @@
|
|||
font-size: 1.15rem
|
||||
|
||||
&:hover
|
||||
background-color: RGBA($primary, 0.2)
|
||||
background-color: var(--primary-transparent)
|
||||
|
|
|
@ -9,11 +9,11 @@
|
|||
height: 100vh
|
||||
|
||||
background-color: transparent
|
||||
color: RGB($fg-white)
|
||||
color: var(--foreground-white)
|
||||
|
||||
overflow: hidden
|
||||
z-index: 68
|
||||
transition: background-color 0.25s cubic-bezier(0.76, 0, 0.17, 1)
|
||||
transition: background-color 0.25s var(--animation-smooth)
|
||||
|
||||
h3
|
||||
margin: 0
|
||||
|
@ -66,11 +66,11 @@
|
|||
flex-direction: column
|
||||
gap: 1rem
|
||||
|
||||
background-color: RGB($bg-200)
|
||||
background-color: var(--background-200)
|
||||
|
||||
z-index: +2
|
||||
|
||||
transition: left 0.25s cubic-bezier(0.76, 0, 0.17, 1), bottom 0.25s cubic-bezier(0.76, 0, 0.17, 1)
|
||||
transition: left 0.25s var(--animation-smooth), bottom 0.25s var(--animation-smooth)
|
||||
|
||||
#dragIndicator
|
||||
display: none
|
||||
|
@ -94,21 +94,21 @@
|
|||
left: 50%
|
||||
transform: translate(-50%, -50%)
|
||||
|
||||
background-color: RGB($bg-400)
|
||||
border-radius: $rad-inner
|
||||
background-color: var(--background-400)
|
||||
border-radius: calc(var(--rad) / 2)
|
||||
|
||||
transition: width 0.25s $animation-bounce
|
||||
transition: width 0.25s var(--animation-smooth)
|
||||
|
||||
&.dragging #dragIndicator::after
|
||||
width: 9rem
|
||||
background-color: RGB($primary)
|
||||
background-color: var(--primary)
|
||||
|
||||
.upload-jobs
|
||||
display: flex
|
||||
flex-direction: column
|
||||
gap: 0.5rem
|
||||
|
||||
border-radius: $rad
|
||||
border-radius: var(--rad)
|
||||
|
||||
overflow-y: auto
|
||||
|
||||
|
@ -123,8 +123,8 @@
|
|||
align-items: center
|
||||
gap: 0.5rem
|
||||
|
||||
background-color: RGB($bg-200)
|
||||
border-radius: $rad
|
||||
background-color: var(--background-200)
|
||||
border-radius: var(--rad)
|
||||
|
||||
overflow: hidden
|
||||
|
||||
|
@ -146,7 +146,7 @@
|
|||
width: 100%
|
||||
height: 100%
|
||||
|
||||
background-image: linear-gradient(to right, RGB($bg-100), transparent)
|
||||
background-image: linear-gradient(to right, var(--background-100), transparent)
|
||||
|
||||
.job__status
|
||||
margin: 0
|
||||
|
@ -159,51 +159,51 @@
|
|||
font-size: 1rem
|
||||
font-weight: 600
|
||||
|
||||
color: RGB($fg-white)
|
||||
color: var(--foreground-white)
|
||||
|
||||
z-index: +3
|
||||
|
||||
transition: color 0.25s cubic-bezier(0.76, 0, 0.17, 1)
|
||||
transition: color 0.25s var(--animation-smooth)
|
||||
|
||||
.progress
|
||||
width: 100%
|
||||
height: $rad-inner
|
||||
height: calc(var(--rad) / 2)
|
||||
|
||||
position: absolute
|
||||
bottom: 0
|
||||
left: -100%
|
||||
|
||||
background-color: RGB($primary)
|
||||
background-color: var(--primary)
|
||||
|
||||
animation: uploadingLoop 1s cubic-bezier(0.76, 0, 0.17, 1) infinite
|
||||
animation: uploadingLoop 1s var(--animation-smooth) infinite
|
||||
|
||||
z-index: +5
|
||||
transition: left 1s cubic-bezier(0.76, 0, 0.17, 1)
|
||||
transition: left 1s var(--animation-smooth)
|
||||
|
||||
&.critical
|
||||
.job__status, .progress
|
||||
color: RGB($critical)
|
||||
color: var(--critical)
|
||||
&.success
|
||||
.job__status
|
||||
color: RGB($success)
|
||||
color: var(--success)
|
||||
.progress
|
||||
height: 0
|
||||
animation: none
|
||||
&.warning
|
||||
.job__status, .progress
|
||||
color: RGB($warning)
|
||||
color: var(--warning)
|
||||
|
||||
&.critical, &.success, &.warning
|
||||
.progress
|
||||
height: 0
|
||||
|
||||
&.open
|
||||
background-color: $bg-transparent
|
||||
background-color: var(--background-shade)
|
||||
|
||||
.container
|
||||
left: 0
|
||||
|
||||
@media (max-width: $breakpoint)
|
||||
@media (max-width: 800px)
|
||||
.upload-panel
|
||||
width: 100%
|
||||
height: calc(100vh - 3.5rem)
|
||||
|
@ -219,7 +219,7 @@
|
|||
left: 0
|
||||
bottom: -100vh
|
||||
|
||||
border-radius: $rad $rad 0 0
|
||||
border-radius: var(--rad) var(--rad) 0 0
|
||||
|
||||
#dragIndicator
|
||||
display: block
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Default theme for OnlyLegs by FluffyBean
|
||||
// Mockup link: https://www.figma.com/file/IMZT5kZr3sAngrSHSGu5di/OnlyLegs?node-id=0%3A1
|
||||
|
||||
|
||||
@import "variables"
|
||||
@import "animations"
|
||||
|
||||
|
@ -15,7 +16,6 @@
|
|||
@import "components/gallery"
|
||||
|
||||
@import "components/buttons/top-of-page"
|
||||
@import "components/buttons/info-button"
|
||||
@import "components/buttons/pill"
|
||||
@import "components/buttons/block"
|
||||
|
||||
|
@ -24,17 +24,17 @@
|
|||
|
||||
*
|
||||
box-sizing: border-box
|
||||
scrollbar-color: RGB($primary) transparent
|
||||
font-family: $font
|
||||
scrollbar-color: var(--primary) transparent
|
||||
font-family: var(--font-family)
|
||||
|
||||
::-webkit-scrollbar
|
||||
width: 0.5rem
|
||||
::-webkit-scrollbar-track
|
||||
background: RGB($bg-200)
|
||||
background: var(--background-200)
|
||||
::-webkit-scrollbar-thumb
|
||||
background: RGB($primary)
|
||||
background: var(--primary)
|
||||
::-webkit-scrollbar-thumb:hover
|
||||
background: RGB($fg-white)
|
||||
background: var(--foreground-white)
|
||||
|
||||
html
|
||||
margin: 0
|
||||
|
@ -51,25 +51,35 @@ body
|
|||
display: grid
|
||||
grid-template-rows: auto 1fr auto
|
||||
|
||||
background-color: RGB($background)
|
||||
color: RGB($foreground)
|
||||
font-family: var(--font-family)
|
||||
|
||||
background-color: var(--background-100)
|
||||
color: var(--foreground-white)
|
||||
|
||||
overflow-x: hidden
|
||||
@media (max-width: $breakpoint)
|
||||
@media (max-width: 800px)
|
||||
body
|
||||
padding: 0 0 3.5rem 0
|
||||
|
||||
main
|
||||
margin: 0 0.5rem 0.5rem 0
|
||||
padding: 0.5rem
|
||||
display: flex
|
||||
flex-direction: column
|
||||
position: relative
|
||||
background: RGBA($white, 1)
|
||||
color: RGB($fg-black)
|
||||
border-top-left-radius: $rad
|
||||
background: var(--background-800)
|
||||
color: var(--foreground-black)
|
||||
border-radius: var(--rad)
|
||||
overflow: hidden
|
||||
@media (max-width: $breakpoint)
|
||||
@media (max-width: 800px)
|
||||
main
|
||||
border-top-left-radius: 0
|
||||
margin: 0 0.5rem
|
||||
|
||||
// This is very broken, as it breaks when you open any context menu/popup
|
||||
// I need to fix this at some point as it looks really nice
|
||||
//header
|
||||
// position: sticky
|
||||
// top: 0
|
||||
|
||||
.error-page
|
||||
min-height: 100%
|
||||
|
@ -86,7 +96,7 @@ main
|
|||
font-weight: 900
|
||||
text-align: center
|
||||
|
||||
color: $primary
|
||||
color: var(--primary)
|
||||
|
||||
p
|
||||
margin: 0 2rem
|
||||
|
@ -95,7 +105,7 @@ main
|
|||
font-size: 1.25rem
|
||||
font-weight: 400
|
||||
text-align: center
|
||||
@media (max-width: $breakpoint)
|
||||
@media (max-width: 800px)
|
||||
.error-page
|
||||
h1
|
||||
font-size: 4.5rem
|
||||
|
|
|
@ -1,80 +1,56 @@
|
|||
$bg-transparent: rgba(var(--bg-dim), 0.8)
|
||||
$bg-dim: var(--bg-dim)
|
||||
$bg-bright: var(--bg-bright)
|
||||
$bg-100: var(--bg-100)
|
||||
$bg-200: var(--bg-200)
|
||||
$bg-300: var(--bg-300)
|
||||
$bg-400: var(--bg-400)
|
||||
$bg-500: var(--bg-500)
|
||||
$bg-600: var(--bg-600)
|
||||
|
||||
$fg-dim: var(--fg-dim)
|
||||
$fg-white: var(--fg-white)
|
||||
$fg-black: var(--fg-black)
|
||||
|
||||
$black: var(--black)
|
||||
$white: var(--white)
|
||||
$red: var(--red)
|
||||
$orange: var(--orange)
|
||||
$yellow: var(--yellow)
|
||||
$green: var(--green)
|
||||
$blue: var(--blue)
|
||||
$purple: var(--purple)
|
||||
|
||||
$primary: var(--primary)
|
||||
$warning: var(--warning)
|
||||
$critical: var(--critical)
|
||||
$success: var(--success)
|
||||
$info: var(--info)
|
||||
|
||||
$rad: var(--rad)
|
||||
$rad-inner: var(--rad-inner)
|
||||
|
||||
$animation-smooth: var(--animation-smooth)
|
||||
$animation-bounce: var(--animation-bounce)
|
||||
|
||||
$font: 'Rubik', sans-serif
|
||||
$breakpoint: 800px
|
||||
|
||||
|
||||
// New variables, Slowly moving over to them because I suck at planning ahead and coding reeee
|
||||
$background: var(--bg-100)
|
||||
$foreground: var(--fg-white)
|
||||
|
||||
|
||||
\:root
|
||||
--bg-dim: 16, 16, 16
|
||||
--bg-bright: 232, 227, 227
|
||||
--bg-100: 21, 21, 21
|
||||
--bg-200: #{red(adjust-color(rgb(21, 21, 21), $lightness: 2%)), green(adjust-color(rgb(21, 21, 21), $lightness: 2%)), blue(adjust-color(rgb(21, 21, 21), $lightness: 2%))}
|
||||
--bg-300: #{red(adjust-color(rgb(21, 21, 21), $lightness: 4%)), green(adjust-color(rgb(21, 21, 21), $lightness: 4%)), blue(adjust-color(rgb(21, 21, 21), $lightness: 4%))}
|
||||
--bg-400: #{red(adjust-color(rgb(21, 21, 21), $lightness: 6%)), green(adjust-color(rgb(21, 21, 21), $lightness: 6%)), blue(adjust-color(rgb(21, 21, 21), $lightness: 6%))}
|
||||
--bg-500: #{red(adjust-color(rgb(21, 21, 21), $lightness: 8%)), green(adjust-color(rgb(21, 21, 21), $lightness: 8%)), blue(adjust-color(rgb(21, 21, 21), $lightness: 8%))}
|
||||
--bg-600: #{red(adjust-color(rgb(21, 21, 21), $lightness: 10%)), green(adjust-color(rgb(21, 21, 21), $lightness: 10%)), blue(adjust-color(rgb(21, 21, 21), $lightness: 10%))}
|
||||
--background-hsl-hue: 69
|
||||
--background-hsl-saturation: 25%
|
||||
|
||||
--fg-dim: 102, 102, 102
|
||||
--fg-white: 232, 227, 227
|
||||
--fg-black: 16, 16, 16
|
||||
--background-100: hsl(var(--background-hsl-hue), var(--background-hsl-saturation), 6%)
|
||||
--background-200: hsl(var(--background-hsl-hue), var(--background-hsl-saturation), 8%)
|
||||
--background-300: hsl(var(--background-hsl-hue), var(--background-hsl-saturation), 10%)
|
||||
--background-400: hsl(var(--background-hsl-hue), var(--background-hsl-saturation), 12%)
|
||||
--background-500: hsl(var(--background-hsl-hue), var(--background-hsl-saturation), 14%)
|
||||
--background-600: hsl(var(--background-hsl-hue), var(--background-hsl-saturation), 16%)
|
||||
--background-700: hsl(var(--background-hsl-hue), var(--background-hsl-saturation), 18%)
|
||||
--background-800: rgb(232, 227, 227)
|
||||
|
||||
--black: 21, 21, 21
|
||||
--white: 232, 227, 227
|
||||
--red: 182, 100, 103
|
||||
--orange: 217, 140, 95
|
||||
--yellow: 217, 188, 140
|
||||
--green: 140, 151, 125
|
||||
--blue: 141, 163, 185
|
||||
--purple: 169, 136, 176
|
||||
--background-shade: hsl(var(--background-hsl-hue), var(--background-hsl-saturation), 6%, 0.5)
|
||||
|
||||
--foreground-white: rgb(232, 227, 227)
|
||||
--foreground-gray: rgb(102, 102, 102)
|
||||
--foreground-black: rgb(16, 16, 16)
|
||||
|
||||
--black: rgb(20, 20, 20)
|
||||
--black-transparent: rgba(20, 20, 20, 0.2)
|
||||
--white: rgb(232, 227, 227)
|
||||
--white-transparent: rgba(232, 227, 227, 0.2)
|
||||
|
||||
--red: rgb(182, 100, 103)
|
||||
--red-transparent: rgba(182, 100, 103, 0.1)
|
||||
--orange: rgb(217, 140, 95)
|
||||
--orange-transparent: rgba(217, 140, 95, 0.1)
|
||||
--yellow: rgb(198, 185, 166)
|
||||
--yellow-transparent: rgba(198, 185, 166, 0.1)
|
||||
--green: rgb(140, 151, 125)
|
||||
--green-transparent: rgba(140, 151, 125, 0.1)
|
||||
--blue: rgb(141, 163, 185)
|
||||
--blue-transparent: rgba(141, 163, 185, 0.1)
|
||||
--purple: rgb(169, 136, 176)
|
||||
--purple-transparent: rgba(169, 136, 176, 0.1)
|
||||
--primary: rgb(183, 169, 151)
|
||||
--primary-transparent: rgba(183, 169, 151, 0.1)
|
||||
|
||||
--primary: var(--green) // 183, 169, 151
|
||||
--warning: var(--orange)
|
||||
--critical: var(--red)
|
||||
--warning-transparent: var(--orange-transparent)
|
||||
--danger: var(--red)
|
||||
--danger-transparent: var(--red-transparent)
|
||||
--success: var(--green)
|
||||
--success-transparent: var(--green-transparent)
|
||||
--info: var(--blue)
|
||||
--info-transparent: var(--blue-transparent)
|
||||
|
||||
--rad: 0.5rem
|
||||
--rad-inner: calc(var(--rad) / 2)
|
||||
--rad: 0.4rem
|
||||
|
||||
--animation-smooth: cubic-bezier(0.76, 0, 0.17, 1)
|
||||
--animation-bounce: cubic-bezier(.68,-0.55,.27,1.55)
|
||||
|
||||
--breakpoint: 800px
|
||||
|
||||
--font-family: 'Switzer', sans-serif
|
||||
|
|
|
@ -17,9 +17,7 @@
|
|||
<meta name="twitter:description" content="{{ config.WEBSITE_CONF.motto }}">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Rubik:ital,wght@0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap">
|
||||
<link href="https://api.fontshare.com/v2/css?f[]=switzer@101,600,701,800,501,601,900,100,700,901,400,201,401,200,300,301,801,500&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- phosphor icons -->
|
||||
<script src="https://unpkg.com/@phosphor-icons/web"></script>
|
||||
|
@ -29,6 +27,23 @@
|
|||
|
||||
{% assets "scripts" %} <script type="text/javascript" src="{{ ASSET_URL }}"></script> {% endassets %}
|
||||
{% assets "styles" %} <link rel="stylesheet" href="{{ ASSET_URL }}" type="text/css" defer> {% endassets %}
|
||||
|
||||
<style>
|
||||
{% if config.WEBSITE_CONF.styling.force %}
|
||||
:root{
|
||||
--background-hsl-hue: {{ config.WEBSITE_CONF.styling.hue }} !important;
|
||||
--background-hsl-saturation: {{ config.WEBSITE_CONF.styling.saturation }}% !important;
|
||||
--rad: {{ config.WEBSITE_CONF.styling.rad }} !important;
|
||||
}
|
||||
{% else %}
|
||||
:root{
|
||||
--background-hsl-hue: {{ config.WEBSITE_CONF.styling.hue }};
|
||||
--background-hsl-saturation: {{ config.WEBSITE_CONF.styling.saturation }}%;
|
||||
--rad: {{ config.WEBSITE_CONF.styling.rad }};
|
||||
}
|
||||
{% endif %}
|
||||
</style>
|
||||
|
||||
{% block head %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
|
@ -123,6 +138,10 @@
|
|||
<script type="text/javascript">
|
||||
keepSquare();
|
||||
|
||||
{% for message in get_flashed_messages() %}
|
||||
addNotification('{{ message[0] }}', {{ message[1] }});
|
||||
{% endfor %}
|
||||
|
||||
const times = document.querySelectorAll('.time');
|
||||
for (let i = 0; i < times.length; i++) {
|
||||
// Remove milliseconds
|
||||
|
@ -184,10 +203,6 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
{% for message in get_flashed_messages() %}
|
||||
addNotification('{{ message[0] }}', {{ message[1] }});
|
||||
{% endfor %}
|
||||
</script>
|
||||
|
||||
{% block script %}{% endblock %}
|
||||
|
|
|
@ -20,40 +20,9 @@
|
|||
|
||||
<style>
|
||||
{% if images %}
|
||||
:root { --bg-100: {{ images.0.colours.0.0 }}, {{ images.0.colours.0.1 }}, {{ images.0.colours.0.2 }} }
|
||||
|
||||
body {
|
||||
background: rgb{{ images.0.colours.0 }} !important;
|
||||
color: {{ text_colour }} !important;
|
||||
}
|
||||
main {
|
||||
background: rgba(var(--white), 0.6) !important;
|
||||
}
|
||||
|
||||
|
||||
.navigation-item.selected { color: {{ text_colour }} !important; }
|
||||
|
||||
.banner .banner-content .banner-header,
|
||||
.banner .banner-content .banner-info,
|
||||
.banner .banner-content .banner-subtitle {
|
||||
color: {{ text_colour }} !important;
|
||||
}
|
||||
.banner-content .link {
|
||||
background-color: {{ text_colour }} !important;
|
||||
color: rgb{{ images.0.colours.0 }} !important;
|
||||
}
|
||||
.banner-content .link:hover {
|
||||
background-color: rgb{{ images.0.colours.0 }} !important;
|
||||
color: {{ text_colour }} !important;
|
||||
}
|
||||
|
||||
.banner-filter {
|
||||
background: linear-gradient(90deg, rgb{{ images.0.colours.0 }}, rgba({{ images.0.colours.1.0 }}, {{ images.0.colours.1.1 }}, {{ images.0.colours.1.2 }}, 0.3)) !important;
|
||||
}
|
||||
@media (max-width: 800px) {
|
||||
.banner-filter {
|
||||
background: linear-gradient(180deg, rgba({{ images.0.colours.1.0 }}, {{ images.0.colours.1.1 }}, {{ images.0.colours.1.2 }}, 0.4), rgba({{ images.0.colours.0.0 }}, {{ images.0.colours.0.1 }}, {{ images.0.colours.0.2 }}, 0.3)) !important;
|
||||
}
|
||||
:root {
|
||||
--background-hsl-hue: {{ images.0.colours.0 | hsl_hue }};
|
||||
--background-hsl-saturation: {{ images.0.colours.0 | hsl_saturation }}%;
|
||||
}
|
||||
{% endif %}
|
||||
</style>
|
||||
|
|
|
@ -18,6 +18,10 @@
|
|||
</script>
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--background-hsl-hue: {{ image.colours.2 | hsl_hue }};
|
||||
--background-hsl-saturation: {{ image.colours.2 | hsl_saturation }}%;
|
||||
}
|
||||
.background::after {
|
||||
background-image: linear-gradient(to top, rgba({{ image.colours.0.0 }}, {{ image.colours.0.1 }}, {{ image.colours.0.2 }}, 0.8),
|
||||
rgba({{ image.colours.1.0 }}, {{ image.colours.1.1 }}, {{ image.colours.1.2 }}, 0.2));
|
||||
|
@ -30,15 +34,23 @@
|
|||
<div class="banner-content">
|
||||
<h1 class="banner-header">{{ config.WEBSITE_CONF.name }}</h1>
|
||||
<div class="pill-row">
|
||||
{% if next_url %}<div><a class="pill-item" href="{{ next_url }}"><i class="ph ph-arrow-left"></i></a></div>{% endif %}
|
||||
<div>
|
||||
<button class="pill-item" onclick="imageFullscreen()"><i class="ph ph-info"></i></button>
|
||||
<a {% if next_url %}class="pill-item" href="{{ next_url }}"{% else %}class="pill-item disabled"{% endif %}>
|
||||
<i class="ph ph-arrow-left"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<button class="pill-item" onclick="imageFullscreen()" id="fullscreenImage"><i class="ph ph-info"></i></button>
|
||||
<button class="pill-item" onclick="copyToClipboard(window.location.href)"><i class="ph ph-export"></i></button>
|
||||
{% if image.author.id == current_user.id %}
|
||||
<button class="pill-item pill__critical" onclick="imageShowOptionsPopup(this)"><i class="ph-fill ph-dots-three-outline-vertical"></i></button>
|
||||
<button class="pill-item" onclick="imageShowOptionsPopup(this)"><i class="ph ph-list"></i></button>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if prev_url %}<div><a class="pill-item" href="{{ prev_url }}"><i class="ph ph-arrow-right"></i></a></div>{% endif %}
|
||||
<div>
|
||||
<a {% if prev_url %}class="pill-item" href="{{ prev_url }}"{% else %}class="pill-item disabled"{% endif %}>
|
||||
<i class="ph ph-arrow-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
{% block header %}
|
||||
<div class="banner">
|
||||
{% if user.banner %}
|
||||
<img src="{{ url_for('static', filename='icon.png') }}" alt="Profile Banner" onload="imgFade(this)" style="opacity:0;"/>
|
||||
<img src="{{ url_for('api.media', path='banner/' + user.banner) }}" alt="Profile Banner" onload="imgFade(this)" style="opacity:0;"/>
|
||||
{% else %}
|
||||
<img src="{{ url_for('static', filename='banner.png') }}" alt="Profile Banner" onload="imgFade(this)" style="opacity:0;"/>
|
||||
{% endif %}
|
||||
|
|
|
@ -16,50 +16,86 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="info-tab" id="profileSettings" style="margin: 0.5rem 0.5rem 0 0.5rem">
|
||||
<div class="info-header">
|
||||
<i class="ph ph-info"></i>
|
||||
<h2>Profile Settings</h2>
|
||||
<button class="collapse-indicator"><i class="ph ph-caret-down"></i></button>
|
||||
</div>
|
||||
<div class="info-table">
|
||||
<form method="POST" action="{{ url_for('api.account_picture', user_id=current_user.id) }}" enctype="multipart/form-data">
|
||||
<h3>Profile Picture</h3>
|
||||
<input type="file" name="file" tab-index="-1"/>
|
||||
<input type="submit" value="Upload" class="btn-block">
|
||||
</form>
|
||||
<form method="POST" action="{{ url_for('api.account_username', user_id=current_user.id) }}" enctype="multipart/form-data">
|
||||
<h3>Username</h3>
|
||||
<input type="text" name="name" class="input-block" value="{{ current_user.username }}" />
|
||||
<input type="submit" value="Upload" class="btn-block"/>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<details open>
|
||||
<summary>
|
||||
<i class="ph ph-info"></i><h2>Profile</h2><span style="width: 100%"></span>
|
||||
<i class="ph ph-caret-down collapse-indicator"></i>
|
||||
</summary>
|
||||
|
||||
<div class="info-tab" id="profileSettings" style="margin: 0.5rem 0.5rem 0 0.5rem">
|
||||
<div class="info-header">
|
||||
<i class="ph ph-info"></i>
|
||||
<h2>Account Settings</h2>
|
||||
<button class="collapse-indicator"><i class="ph ph-caret-down"></i></button>
|
||||
</div>
|
||||
<div class="info-table">
|
||||
<form method="POST" action="" enctype="multipart/form-data">
|
||||
<h3>Email</h3>
|
||||
<input type="text" name="email" class="input-block" value="{{ current_user.email }}" />
|
||||
<input type="submit" value="Upload" class="btn-block"/>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<form method="POST" action="{{ url_for('settings.account_picture') }}" enctype="multipart/form-data">
|
||||
<h3>Profile Picture</h3>
|
||||
<input type="file" name="file" tab-index="-1"/>
|
||||
<button type="submit" class="btn-block">Change Profile Picture</button>
|
||||
</form>
|
||||
<form method="POST" action="{{ url_for('settings.account_banner') }}" enctype="multipart/form-data">
|
||||
<h3>Profile Banner</h3>
|
||||
<input type="file" name="file" tab-index="-1"/>
|
||||
<button type="submit" class="btn-block">Change Profile Banner</button>
|
||||
</form>
|
||||
<form method="POST" action="{{ url_for('settings.account_username') }}" enctype="multipart/form-data">
|
||||
<h3>Username</h3>
|
||||
<input type="text" name="name" class="input-block" value="{{ current_user.username }}" />
|
||||
<button type="submit" class="btn-block">Change Username</button>
|
||||
</form>
|
||||
</details>
|
||||
|
||||
<details open>
|
||||
<summary>
|
||||
<i class="ph ph-info"></i><h2>Account</h2><span style="width: 100%"></span>
|
||||
<i class="ph ph-caret-down collapse-indicator"></i>
|
||||
</summary>
|
||||
|
||||
<form method="POST" action="{{ url_for('settings.account_email') }}" enctype="multipart/form-data">
|
||||
<h3>Email</h3>
|
||||
<input type="text" name="email" class="input-block" value="{{ current_user.email }}" />
|
||||
<input type="password" name="current" class="input-block" placeholder="Current Password" />
|
||||
<button type="submit" class="btn-block">Change Email</button>
|
||||
</form>
|
||||
<form method="POST" action="{{ url_for('settings.account_password') }}" enctype="multipart/form-data">
|
||||
<h3>Password</h3>
|
||||
<input type="password" name="current" class="input-block" placeholder="Current Password" />
|
||||
<input type="password" name="password" class="input-block" placeholder="New Password" />
|
||||
<input type="password" name="confirm" class="input-block" placeholder="Confirm Password" />
|
||||
<button type="submit" class="btn-block">Change Password</button>
|
||||
</form>
|
||||
</details>
|
||||
|
||||
<details open>
|
||||
<summary>
|
||||
<i class="ph ph-info"></i><h2>Server</h2><span style="width: 100%"></span>
|
||||
<i class="ph ph-caret-down collapse-indicator"></i>
|
||||
</summary>
|
||||
|
||||
<form method="POST" action="{{ url_for('settings.website_style') }}" enctype="multipart/form-data">
|
||||
<h3>Style</h3>
|
||||
<input type="range" name="hue" class="input-block" placeholder="Website Hue" value="{{ config.WEBSITE_CONF.styling.hue }}" min="0" max="360" />
|
||||
<input type="range" name="saturation" class="input-block" placeholder="Strength of Color" value="{{ config.WEBSITE_CONF.styling.saturation }}" min="0" max="100" />
|
||||
<input type="text" name="rad" class="input-block" placeholder="Roundy roundy" value="{{ config.WEBSITE_CONF.styling.rad }}" />
|
||||
<input type="checkbox" name="force" class="input-block" placeholder="Force styling?" {% if config.WEBSITE_CONF.styling.force %}checked{% endif %} />
|
||||
<button type="submit" class="btn-block">Update style</button>
|
||||
</form>
|
||||
</details>
|
||||
|
||||
<footer>
|
||||
<p>Built on coffee and love, by Fluffy</p>
|
||||
</footer>
|
||||
{% endblock %}
|
||||
|
||||
{% block script %}
|
||||
<script type="text/javascript">
|
||||
let infoTab = document.querySelectorAll('.info-tab');
|
||||
<script>
|
||||
let hue = document.querySelector('input[name=hue]');
|
||||
let saturation = document.querySelector('input[name=saturation]');
|
||||
let rad = document.querySelector('input[name=rad]');
|
||||
|
||||
for (let i = 0; i < infoTab.length; i++) {
|
||||
infoTab[i].querySelector('.collapse-indicator').addEventListener('click', function() {
|
||||
infoTab[i].classList.toggle('collapsed');
|
||||
});
|
||||
}
|
||||
hue.addEventListener('input', () => {
|
||||
document.documentElement.style.setProperty('--background-hsl-hue', hue.value, 'important');
|
||||
});
|
||||
saturation.addEventListener('input', () => {
|
||||
document.documentElement.style.setProperty('--background-hsl-saturation', saturation.value + '%', 'important');
|
||||
});
|
||||
rad.addEventListener('input', () => {
|
||||
document.documentElement.style.setProperty('--rad', rad.value, 'important');
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ class Colour:
|
|||
s = 0.0
|
||||
else:
|
||||
d = high - low
|
||||
s = d / (2 - high - low) if l > 0.5 else d / (high + low)
|
||||
s = d / (2 - high - low) if low > 0.5 else d / (high + low)
|
||||
h = {
|
||||
r: (g - b) / d + (6 if g < b else 0),
|
||||
g: (b - r) / d + 2,
|
||||
|
|
133
onlylegs/utils/startup.py
Normal file
133
onlylegs/utils/startup.py
Normal file
|
@ -0,0 +1,133 @@
|
|||
"""
|
||||
OnlyLegs - Setup
|
||||
Runs when the app detects that there is no user directory
|
||||
"""
|
||||
import os
|
||||
import re
|
||||
import platformdirs
|
||||
import yaml
|
||||
|
||||
|
||||
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"),
|
||||
"banner": os.path.join(APPLICATION_ROOT, "media", "banner"),
|
||||
}
|
||||
|
||||
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")
|
||||
|
||||
config = {
|
||||
# Version of the config file
|
||||
"version": "0.1.7",
|
||||
# Not really used much, but good to have for future use
|
||||
"admin": {
|
||||
"username": "admin",
|
||||
"email": "admin@example.com",
|
||||
},
|
||||
"upload": {
|
||||
"allowed-extensions": {
|
||||
"jpg": "jpeg",
|
||||
"jpeg": "jpeg",
|
||||
"png": "png",
|
||||
"webp": "webp",
|
||||
},
|
||||
# Max size in MB
|
||||
"max-size": 69,
|
||||
# Max images to load per page
|
||||
"max-load": 50,
|
||||
},
|
||||
"website": {
|
||||
# Website name and motto
|
||||
# Also CSS styling, hue is the color offset for hsl
|
||||
"name": "OnlyLegs",
|
||||
"motto": "A gallery built for fast and simple image management!",
|
||||
"styling": {
|
||||
"force": False,
|
||||
"hue": "69",
|
||||
"saturation": "25%",
|
||||
"rad": "0.4rem",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def check_dirs():
|
||||
for directory in REQUIRED_DIRS.values():
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
print("Created directory at:", directory)
|
||||
print("User directory already exists at:", directory)
|
||||
|
||||
|
||||
def check_env():
|
||||
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():
|
||||
config_file = os.path.join(APPLICATION_ROOT, "conf.yml")
|
||||
if os.path.exists(config_file):
|
||||
print("Config file already exists at:", APPLICATION_ROOT)
|
||||
return
|
||||
|
||||
cant_continue = True
|
||||
username = "admin"
|
||||
email = "admin@example.com"
|
||||
|
||||
print("No config file found, please enter the following information:")
|
||||
while cant_continue:
|
||||
username = input("Admin username: ").strip()
|
||||
email = input("Admin email: ").strip()
|
||||
|
||||
if not username or not USERNAME_REGEX.match(username):
|
||||
print("Username 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
|
||||
is_correct = input("Is this correct? (Y/n): ").lower().strip()
|
||||
if is_correct == "y" or not is_correct:
|
||||
cant_continue = False
|
||||
|
||||
config["admin"]["username"] = username
|
||||
config["admin"]["email"] = email
|
||||
|
||||
with open(config_file, encoding="utf-8", mode="w+") as file:
|
||||
yaml.dump(config, file, default_flow_style=False)
|
||||
|
||||
print(
|
||||
"####################################################",
|
||||
"# A NEW CONFIG HAS BEEN GENERATED AT: #",
|
||||
"# ~/.config/onlylegs/conf.yml #",
|
||||
"####################################################",
|
||||
sep="\n",
|
||||
)
|
|
@ -1,17 +1,191 @@
|
|||
"""
|
||||
OnlyLegs - Settings page
|
||||
"""
|
||||
from flask import Blueprint, render_template
|
||||
from flask_login import login_required
|
||||
import os
|
||||
import pathlib
|
||||
import re
|
||||
import logging
|
||||
import yaml
|
||||
from colorthief import ColorThief
|
||||
from flask import (
|
||||
Blueprint,
|
||||
request,
|
||||
current_app,
|
||||
render_template,
|
||||
flash,
|
||||
redirect,
|
||||
url_for,
|
||||
)
|
||||
from flask_login import login_required, current_user
|
||||
from werkzeug.security import check_password_hash, generate_password_hash
|
||||
from onlylegs.extensions import db
|
||||
from onlylegs.models import Users
|
||||
from onlylegs.config import APPLICATION_ROOT
|
||||
|
||||
|
||||
blueprint = Blueprint("settings", __name__, url_prefix="/settings")
|
||||
|
||||
|
||||
@blueprint.route("/")
|
||||
@blueprint.route("/", methods=["GET"])
|
||||
@login_required
|
||||
def general():
|
||||
"""
|
||||
General settings page
|
||||
"""
|
||||
return render_template("settings.html")
|
||||
|
||||
|
||||
@blueprint.route("/account/pfp", methods=["POST"])
|
||||
@login_required
|
||||
def account_picture():
|
||||
user_record = Users.query.filter_by(id=current_user.id).first()
|
||||
uploaded_file = request.files.get("file", None)
|
||||
if not uploaded_file:
|
||||
return "No file uploaded!", 400
|
||||
|
||||
image_mime = pathlib.Path(uploaded_file.filename).suffix.replace(".", "").lower()
|
||||
image_name = str(user_record.id) + "_pfp." + image_mime
|
||||
image_path = os.path.join(current_app.config["PFP_FOLDER"], image_name)
|
||||
|
||||
if image_mime not in current_app.config["ALLOWED_EXTENSIONS"].keys():
|
||||
logging.info("File extension not allowed: %s", image_mime)
|
||||
return "File extension not allowed", 403
|
||||
|
||||
if user_record.picture:
|
||||
os.remove(os.path.join(current_app.config["PFP_FOLDER"], user_record.picture))
|
||||
cache_name = user_record.picture.rsplit(".")[0]
|
||||
for file in pathlib.Path(current_app.config["CACHE_FOLDER"]).glob(
|
||||
cache_name + "*"
|
||||
):
|
||||
os.remove(file)
|
||||
|
||||
uploaded_file.save(image_path)
|
||||
image_colours = ColorThief(image_path).get_color()
|
||||
|
||||
user_record.colour = image_colours
|
||||
user_record.picture = image_name
|
||||
db.session.commit()
|
||||
|
||||
return "File uploaded", 200
|
||||
|
||||
|
||||
@blueprint.route("/account/banner", methods=["POST"])
|
||||
@login_required
|
||||
def account_banner():
|
||||
user_record = Users.query.filter_by(id=current_user.id).first()
|
||||
uploaded_file = request.files.get("file", None)
|
||||
if not uploaded_file:
|
||||
return "No file uploaded!", 400
|
||||
|
||||
image_mime = pathlib.Path(uploaded_file.filename).suffix.replace(".", "").lower()
|
||||
image_name = str(user_record.id) + "_banner." + image_mime
|
||||
image_path = os.path.join(current_app.config["BANNER_FOLDER"], image_name)
|
||||
|
||||
if image_mime not in current_app.config["ALLOWED_EXTENSIONS"].keys():
|
||||
logging.info("File extension not allowed: %s", image_mime)
|
||||
return "File extension not allowed", 403
|
||||
|
||||
if user_record.banner:
|
||||
os.remove(os.path.join(current_app.config["BANNER_FOLDER"], user_record.banner))
|
||||
cache_name = user_record.banner.rsplit(".")[0]
|
||||
for file in pathlib.Path(current_app.config["CACHE_FOLDER"]).glob(
|
||||
cache_name + "*"
|
||||
):
|
||||
os.remove(file)
|
||||
|
||||
uploaded_file.save(image_path)
|
||||
user_record.banner = image_name
|
||||
db.session.commit()
|
||||
|
||||
return "File uploaded", 200
|
||||
|
||||
|
||||
@blueprint.route("/account/username", methods=["POST"])
|
||||
@login_required
|
||||
def account_username():
|
||||
user_record = Users.query.filter_by(id=current_user.id).first()
|
||||
new_username = request.form.get("username", "").strip()
|
||||
|
||||
username_regex = re.compile(r"\b[A-Za-z0-9._-]+\b")
|
||||
|
||||
if not new_username or not username_regex.match(new_username):
|
||||
return "Username is invalid", 400
|
||||
|
||||
user_record.username = new_username
|
||||
db.session.commit()
|
||||
|
||||
return "Username changed", 200
|
||||
|
||||
|
||||
@blueprint.route("/account/email", methods=["POST"])
|
||||
@login_required
|
||||
def account_email():
|
||||
user_record = Users.query.filter_by(id=current_user.id).first()
|
||||
current_password = request.form.get("current", "").strip()
|
||||
new_email = request.form.get("email", "").strip()
|
||||
|
||||
email_regex = re.compile(r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b")
|
||||
|
||||
if not current_password or not new_email:
|
||||
return "Fill in all the fields!", 400
|
||||
if not email_regex.match(new_email):
|
||||
return "Email is invalid!", 400
|
||||
if not check_password_hash(user_record.password, current_password):
|
||||
return "Incorrect password!", 400
|
||||
|
||||
user_record.email = new_email
|
||||
db.session.commit()
|
||||
|
||||
return "Email changed", 200
|
||||
|
||||
|
||||
@blueprint.route("/account/password", methods=["POST"])
|
||||
@login_required
|
||||
def account_password():
|
||||
user_record = Users.query.filter_by(id=current_user.id).first()
|
||||
current_password = request.form.get("current", "").strip()
|
||||
new_password = request.form.get("password", "").strip()
|
||||
new_confirm = request.form.get("confirm", "").strip()
|
||||
|
||||
if not current_password or not new_password or not new_confirm:
|
||||
return "Fill in all the fields!", 400
|
||||
if new_password != new_confirm:
|
||||
return "Passwords do not match!", 400
|
||||
if not check_password_hash(user_record.password, current_password):
|
||||
return "Incorrect password!", 400
|
||||
|
||||
user_record.password = generate_password_hash(new_password, method="scrypt")
|
||||
db.session.commit()
|
||||
|
||||
flash(["Password changed! You must login now", 0])
|
||||
return redirect(url_for("auth.logout"))
|
||||
|
||||
|
||||
@blueprint.route("/website/style", methods=["POST"])
|
||||
@login_required
|
||||
def website_style():
|
||||
config_file = os.path.join(APPLICATION_ROOT, "conf.yml")
|
||||
|
||||
website_hue = request.form.get("hue", 69, type=int)
|
||||
website_saturation = request.form.get("saturation", 25, type=int)
|
||||
website_rad = request.form.get("rad", "0.4rem").strip()
|
||||
website_force_styling = request.form.get("force", False)
|
||||
|
||||
config = None
|
||||
with open(config_file, "r") as file:
|
||||
config = yaml.safe_load(file)
|
||||
|
||||
current_app.config["WEBSITE_CONF"]["styling"]["hue"] = website_hue
|
||||
current_app.config["WEBSITE_CONF"]["styling"]["saturation"] = website_saturation
|
||||
current_app.config["WEBSITE_CONF"]["styling"]["rad"] = website_rad
|
||||
current_app.config["WEBSITE_CONF"]["styling"]["force"] = website_force_styling
|
||||
|
||||
config["website"]["styling"]["hue"] = website_hue
|
||||
config["website"]["styling"]["saturation"] = website_saturation
|
||||
config["website"]["styling"]["rad"] = website_rad
|
||||
config["website"]["styling"]["force"] = website_force_styling
|
||||
|
||||
with open(config_file, "w") as file:
|
||||
yaml.dump(config, file)
|
||||
|
||||
return "Website style changed", 200
|
||||
|
|
662
poetry.lock
generated
662
poetry.lock
generated
|
@ -1,15 +1,15 @@
|
|||
# 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]]
|
||||
name = "alembic"
|
||||
version = "1.11.2"
|
||||
version = "1.12.0"
|
||||
description = "A database migration tool for SQLAlchemy."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "alembic-1.11.2-py3-none-any.whl", hash = "sha256:7981ab0c4fad4fe1be0cf183aae17689fe394ff874fd2464adb774396faf0796"},
|
||||
{file = "alembic-1.11.2.tar.gz", hash = "sha256:678f662130dc540dac12de0ea73de9f89caea9dbea138f60ef6263149bf84657"},
|
||||
{file = "alembic-1.12.0-py3-none-any.whl", hash = "sha256:03226222f1cf943deee6c85d9464261a6c710cd19b4fe867a3ad1f25afda610f"},
|
||||
{file = "alembic-1.12.0.tar.gz", hash = "sha256:8e7645c32e4f200675e69f0745415335eb59a3663f5feb487abfa0b30c45888b"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
@ -24,14 +24,14 @@ tz = ["python-dateutil"]
|
|||
|
||||
[[package]]
|
||||
name = "astroid"
|
||||
version = "2.15.6"
|
||||
version = "2.15.8"
|
||||
description = "An abstract syntax tree for Python with inference support."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7.2"
|
||||
files = [
|
||||
{file = "astroid-2.15.6-py3-none-any.whl", hash = "sha256:389656ca57b6108f939cf5d2f9a2a825a3be50ba9d589670f393236e0a03b91c"},
|
||||
{file = "astroid-2.15.6.tar.gz", hash = "sha256:903f024859b7c7687d7a7f3a3f73b17301f8e42dfd9cc9df9d4418172d3e2dbd"},
|
||||
{file = "astroid-2.15.8-py3-none-any.whl", hash = "sha256:1aa149fc5c6589e3d0ece885b4491acd80af4f087baafa3fb5203b113e68cd3c"},
|
||||
{file = "astroid-2.15.8.tar.gz", hash = "sha256:6c107453dffee9055899705de3c9ead36e74119cee151e5a9aaf7f0b0e020a6a"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
@ -44,34 +44,34 @@ wrapt = [
|
|||
|
||||
[[package]]
|
||||
name = "black"
|
||||
version = "23.7.0"
|
||||
version = "23.9.1"
|
||||
description = "The uncompromising code formatter."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "black-23.7.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:5c4bc552ab52f6c1c506ccae05681fab58c3f72d59ae6e6639e8885e94fe2587"},
|
||||
{file = "black-23.7.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:552513d5cd5694590d7ef6f46e1767a4df9af168d449ff767b13b084c020e63f"},
|
||||
{file = "black-23.7.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:86cee259349b4448adb4ef9b204bb4467aae74a386bce85d56ba4f5dc0da27be"},
|
||||
{file = "black-23.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:501387a9edcb75d7ae8a4412bb8749900386eaef258f1aefab18adddea1936bc"},
|
||||
{file = "black-23.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:fb074d8b213749fa1d077d630db0d5f8cc3b2ae63587ad4116e8a436e9bbe995"},
|
||||
{file = "black-23.7.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:b5b0ee6d96b345a8b420100b7d71ebfdd19fab5e8301aff48ec270042cd40ac2"},
|
||||
{file = "black-23.7.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:893695a76b140881531062d48476ebe4a48f5d1e9388177e175d76234ca247cd"},
|
||||
{file = "black-23.7.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:c333286dc3ddca6fdff74670b911cccedacb4ef0a60b34e491b8a67c833b343a"},
|
||||
{file = "black-23.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831d8f54c3a8c8cf55f64d0422ee875eecac26f5f649fb6c1df65316b67c8926"},
|
||||
{file = "black-23.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:7f3bf2dec7d541b4619b8ce526bda74a6b0bffc480a163fed32eb8b3c9aed8ad"},
|
||||
{file = "black-23.7.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:f9062af71c59c004cd519e2fb8f5d25d39e46d3af011b41ab43b9c74e27e236f"},
|
||||
{file = "black-23.7.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:01ede61aac8c154b55f35301fac3e730baf0c9cf8120f65a9cd61a81cfb4a0c3"},
|
||||
{file = "black-23.7.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:327a8c2550ddc573b51e2c352adb88143464bb9d92c10416feb86b0f5aee5ff6"},
|
||||
{file = "black-23.7.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1c6022b86f83b632d06f2b02774134def5d4d4f1dac8bef16d90cda18ba28a"},
|
||||
{file = "black-23.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:27eb7a0c71604d5de083757fbdb245b1a4fae60e9596514c6ec497eb63f95320"},
|
||||
{file = "black-23.7.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:8417dbd2f57b5701492cd46edcecc4f9208dc75529bcf76c514864e48da867d9"},
|
||||
{file = "black-23.7.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:47e56d83aad53ca140da0af87678fb38e44fd6bc0af71eebab2d1f59b1acf1d3"},
|
||||
{file = "black-23.7.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:25cc308838fe71f7065df53aedd20327969d05671bac95b38fdf37ebe70ac087"},
|
||||
{file = "black-23.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:642496b675095d423f9b8448243336f8ec71c9d4d57ec17bf795b67f08132a91"},
|
||||
{file = "black-23.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:ad0014efc7acf0bd745792bd0d8857413652979200ab924fbf239062adc12491"},
|
||||
{file = "black-23.7.0-py3-none-any.whl", hash = "sha256:9fd59d418c60c0348505f2ddf9609c1e1de8e7493eab96198fc89d9f865e7a96"},
|
||||
{file = "black-23.7.0.tar.gz", hash = "sha256:022a582720b0d9480ed82576c920a8c1dde97cc38ff11d8d8859b3bd6ca9eedb"},
|
||||
{file = "black-23.9.1-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:d6bc09188020c9ac2555a498949401ab35bb6bf76d4e0f8ee251694664df6301"},
|
||||
{file = "black-23.9.1-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:13ef033794029b85dfea8032c9d3b92b42b526f1ff4bf13b2182ce4e917f5100"},
|
||||
{file = "black-23.9.1-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:75a2dc41b183d4872d3a500d2b9c9016e67ed95738a3624f4751a0cb4818fe71"},
|
||||
{file = "black-23.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13a2e4a93bb8ca74a749b6974925c27219bb3df4d42fc45e948a5d9feb5122b7"},
|
||||
{file = "black-23.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:adc3e4442eef57f99b5590b245a328aad19c99552e0bdc7f0b04db6656debd80"},
|
||||
{file = "black-23.9.1-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:8431445bf62d2a914b541da7ab3e2b4f3bc052d2ccbf157ebad18ea126efb91f"},
|
||||
{file = "black-23.9.1-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:8fc1ddcf83f996247505db6b715294eba56ea9372e107fd54963c7553f2b6dfe"},
|
||||
{file = "black-23.9.1-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:7d30ec46de88091e4316b17ae58bbbfc12b2de05e069030f6b747dfc649ad186"},
|
||||
{file = "black-23.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:031e8c69f3d3b09e1aa471a926a1eeb0b9071f80b17689a655f7885ac9325a6f"},
|
||||
{file = "black-23.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:538efb451cd50f43aba394e9ec7ad55a37598faae3348d723b59ea8e91616300"},
|
||||
{file = "black-23.9.1-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:638619a559280de0c2aa4d76f504891c9860bb8fa214267358f0a20f27c12948"},
|
||||
{file = "black-23.9.1-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:a732b82747235e0542c03bf352c126052c0fbc458d8a239a94701175b17d4855"},
|
||||
{file = "black-23.9.1-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:cf3a4d00e4cdb6734b64bf23cd4341421e8953615cba6b3670453737a72ec204"},
|
||||
{file = "black-23.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf99f3de8b3273a8317681d8194ea222f10e0133a24a7548c73ce44ea1679377"},
|
||||
{file = "black-23.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:14f04c990259576acd093871e7e9b14918eb28f1866f91968ff5524293f9c573"},
|
||||
{file = "black-23.9.1-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:c619f063c2d68f19b2d7270f4cf3192cb81c9ec5bc5ba02df91471d0b88c4c5c"},
|
||||
{file = "black-23.9.1-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:6a3b50e4b93f43b34a9d3ef00d9b6728b4a722c997c99ab09102fd5efdb88325"},
|
||||
{file = "black-23.9.1-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:c46767e8df1b7beefb0899c4a95fb43058fa8500b6db144f4ff3ca38eb2f6393"},
|
||||
{file = "black-23.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50254ebfa56aa46a9fdd5d651f9637485068a1adf42270148cd101cdf56e0ad9"},
|
||||
{file = "black-23.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:403397c033adbc45c2bd41747da1f7fc7eaa44efbee256b53842470d4ac5a70f"},
|
||||
{file = "black-23.9.1-py3-none-any.whl", hash = "sha256:6ccd59584cc834b6d127628713e4b6b968e5f79572da66284532525a042549f9"},
|
||||
{file = "black-23.9.1.tar.gz", hash = "sha256:24b6b3ff5c6d9ea08a8888f6977eae858e1f340d7260cf56d70a49823236b62d"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
@ -81,7 +81,7 @@ packaging = ">=22.0"
|
|||
pathspec = ">=0.9.0"
|
||||
platformdirs = ">=2"
|
||||
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
|
||||
typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}
|
||||
typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""}
|
||||
|
||||
[package.extras]
|
||||
colorama = ["colorama (>=0.4.3)"]
|
||||
|
@ -103,96 +103,137 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "brotli"
|
||||
version = "1.0.9"
|
||||
version = "1.1.0"
|
||||
description = "Python bindings for the Brotli compression library"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "Brotli-1.0.9-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:268fe94547ba25b58ebc724680609c8ee3e5a843202e9a381f6f9c5e8bdb5c70"},
|
||||
{file = "Brotli-1.0.9-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:c2415d9d082152460f2bd4e382a1e85aed233abc92db5a3880da2257dc7daf7b"},
|
||||
{file = "Brotli-1.0.9-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5913a1177fc36e30fcf6dc868ce23b0453952c78c04c266d3149b3d39e1410d6"},
|
||||
{file = "Brotli-1.0.9-cp27-cp27m-win32.whl", hash = "sha256:afde17ae04d90fbe53afb628f7f2d4ca022797aa093e809de5c3cf276f61bbfa"},
|
||||
{file = "Brotli-1.0.9-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7cb81373984cc0e4682f31bc3d6be9026006d96eecd07ea49aafb06897746452"},
|
||||
{file = "Brotli-1.0.9-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:db844eb158a87ccab83e868a762ea8024ae27337fc7ddcbfcddd157f841fdfe7"},
|
||||
{file = "Brotli-1.0.9-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9744a863b489c79a73aba014df554b0e7a0fc44ef3f8a0ef2a52919c7d155031"},
|
||||
{file = "Brotli-1.0.9-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a72661af47119a80d82fa583b554095308d6a4c356b2a554fdc2799bc19f2a43"},
|
||||
{file = "Brotli-1.0.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ee83d3e3a024a9618e5be64648d6d11c37047ac48adff25f12fa4226cf23d1c"},
|
||||
{file = "Brotli-1.0.9-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:19598ecddd8a212aedb1ffa15763dd52a388518c4550e615aed88dc3753c0f0c"},
|
||||
{file = "Brotli-1.0.9-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:44bb8ff420c1d19d91d79d8c3574b8954288bdff0273bf788954064d260d7ab0"},
|
||||
{file = "Brotli-1.0.9-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e23281b9a08ec338469268f98f194658abfb13658ee98e2b7f85ee9dd06caa91"},
|
||||
{file = "Brotli-1.0.9-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3496fc835370da351d37cada4cf744039616a6db7d13c430035e901443a34daa"},
|
||||
{file = "Brotli-1.0.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b83bb06a0192cccf1eb8d0a28672a1b79c74c3a8a5f2619625aeb6f28b3a82bb"},
|
||||
{file = "Brotli-1.0.9-cp310-cp310-win32.whl", hash = "sha256:26d168aac4aaec9a4394221240e8a5436b5634adc3cd1cdf637f6645cecbf181"},
|
||||
{file = "Brotli-1.0.9-cp310-cp310-win_amd64.whl", hash = "sha256:622a231b08899c864eb87e85f81c75e7b9ce05b001e59bbfbf43d4a71f5f32b2"},
|
||||
{file = "Brotli-1.0.9-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cc0283a406774f465fb45ec7efb66857c09ffefbe49ec20b7882eff6d3c86d3a"},
|
||||
{file = "Brotli-1.0.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:11d3283d89af7033236fa4e73ec2cbe743d4f6a81d41bd234f24bf63dde979df"},
|
||||
{file = "Brotli-1.0.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c1306004d49b84bd0c4f90457c6f57ad109f5cc6067a9664e12b7b79a9948ad"},
|
||||
{file = "Brotli-1.0.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1375b5d17d6145c798661b67e4ae9d5496920d9265e2f00f1c2c0b5ae91fbde"},
|
||||
{file = "Brotli-1.0.9-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cab1b5964b39607a66adbba01f1c12df2e55ac36c81ec6ed44f2fca44178bf1a"},
|
||||
{file = "Brotli-1.0.9-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8ed6a5b3d23ecc00ea02e1ed8e0ff9a08f4fc87a1f58a2530e71c0f48adf882f"},
|
||||
{file = "Brotli-1.0.9-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cb02ed34557afde2d2da68194d12f5719ee96cfb2eacc886352cb73e3808fc5d"},
|
||||
{file = "Brotli-1.0.9-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b3523f51818e8f16599613edddb1ff924eeb4b53ab7e7197f85cbc321cdca32f"},
|
||||
{file = "Brotli-1.0.9-cp311-cp311-win32.whl", hash = "sha256:ba72d37e2a924717990f4d7482e8ac88e2ef43fb95491eb6e0d124d77d2a150d"},
|
||||
{file = "Brotli-1.0.9-cp311-cp311-win_amd64.whl", hash = "sha256:3ffaadcaeafe9d30a7e4e1e97ad727e4f5610b9fa2f7551998471e3736738679"},
|
||||
{file = "Brotli-1.0.9-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:c83aa123d56f2e060644427a882a36b3c12db93727ad7a7b9efd7d7f3e9cc2c4"},
|
||||
{file = "Brotli-1.0.9-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:6b2ae9f5f67f89aade1fab0f7fd8f2832501311c363a21579d02defa844d9296"},
|
||||
{file = "Brotli-1.0.9-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:68715970f16b6e92c574c30747c95cf8cf62804569647386ff032195dc89a430"},
|
||||
{file = "Brotli-1.0.9-cp35-cp35m-win32.whl", hash = "sha256:defed7ea5f218a9f2336301e6fd379f55c655bea65ba2476346340a0ce6f74a1"},
|
||||
{file = "Brotli-1.0.9-cp35-cp35m-win_amd64.whl", hash = "sha256:88c63a1b55f352b02c6ffd24b15ead9fc0e8bf781dbe070213039324922a2eea"},
|
||||
{file = "Brotli-1.0.9-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:503fa6af7da9f4b5780bb7e4cbe0c639b010f12be85d02c99452825dd0feef3f"},
|
||||
{file = "Brotli-1.0.9-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:40d15c79f42e0a2c72892bf407979febd9cf91f36f495ffb333d1d04cebb34e4"},
|
||||
{file = "Brotli-1.0.9-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:93130612b837103e15ac3f9cbacb4613f9e348b58b3aad53721d92e57f96d46a"},
|
||||
{file = "Brotli-1.0.9-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87fdccbb6bb589095f413b1e05734ba492c962b4a45a13ff3408fa44ffe6479b"},
|
||||
{file = "Brotli-1.0.9-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:6d847b14f7ea89f6ad3c9e3901d1bc4835f6b390a9c71df999b0162d9bb1e20f"},
|
||||
{file = "Brotli-1.0.9-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:495ba7e49c2db22b046a53b469bbecea802efce200dffb69b93dd47397edc9b6"},
|
||||
{file = "Brotli-1.0.9-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:4688c1e42968ba52e57d8670ad2306fe92e0169c6f3af0089be75bbac0c64a3b"},
|
||||
{file = "Brotli-1.0.9-cp36-cp36m-win32.whl", hash = "sha256:61a7ee1f13ab913897dac7da44a73c6d44d48a4adff42a5701e3239791c96e14"},
|
||||
{file = "Brotli-1.0.9-cp36-cp36m-win_amd64.whl", hash = "sha256:1c48472a6ba3b113452355b9af0a60da5c2ae60477f8feda8346f8fd48e3e87c"},
|
||||
{file = "Brotli-1.0.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3b78a24b5fd13c03ee2b7b86290ed20efdc95da75a3557cc06811764d5ad1126"},
|
||||
{file = "Brotli-1.0.9-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:9d12cf2851759b8de8ca5fde36a59c08210a97ffca0eb94c532ce7b17c6a3d1d"},
|
||||
{file = "Brotli-1.0.9-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:6c772d6c0a79ac0f414a9f8947cc407e119b8598de7621f39cacadae3cf57d12"},
|
||||
{file = "Brotli-1.0.9-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29d1d350178e5225397e28ea1b7aca3648fcbab546d20e7475805437bfb0a130"},
|
||||
{file = "Brotli-1.0.9-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7bbff90b63328013e1e8cb50650ae0b9bac54ffb4be6104378490193cd60f85a"},
|
||||
{file = "Brotli-1.0.9-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ec1947eabbaf8e0531e8e899fc1d9876c179fc518989461f5d24e2223395a9e3"},
|
||||
{file = "Brotli-1.0.9-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:12effe280b8ebfd389022aa65114e30407540ccb89b177d3fbc9a4f177c4bd5d"},
|
||||
{file = "Brotli-1.0.9-cp37-cp37m-win32.whl", hash = "sha256:f909bbbc433048b499cb9db9e713b5d8d949e8c109a2a548502fb9aa8630f0b1"},
|
||||
{file = "Brotli-1.0.9-cp37-cp37m-win_amd64.whl", hash = "sha256:97f715cf371b16ac88b8c19da00029804e20e25f30d80203417255d239f228b5"},
|
||||
{file = "Brotli-1.0.9-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e16eb9541f3dd1a3e92b89005e37b1257b157b7256df0e36bd7b33b50be73bcb"},
|
||||
{file = "Brotli-1.0.9-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:160c78292e98d21e73a4cc7f76a234390e516afcd982fa17e1422f7c6a9ce9c8"},
|
||||
{file = "Brotli-1.0.9-cp38-cp38-manylinux1_i686.whl", hash = "sha256:b663f1e02de5d0573610756398e44c130add0eb9a3fc912a09665332942a2efb"},
|
||||
{file = "Brotli-1.0.9-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:5b6ef7d9f9c38292df3690fe3e302b5b530999fa90014853dcd0d6902fb59f26"},
|
||||
{file = "Brotli-1.0.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a674ac10e0a87b683f4fa2b6fa41090edfd686a6524bd8dedbd6138b309175c"},
|
||||
{file = "Brotli-1.0.9-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e2d9e1cbc1b25e22000328702b014227737756f4b5bf5c485ac1d8091ada078b"},
|
||||
{file = "Brotli-1.0.9-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b336c5e9cf03c7be40c47b5fd694c43c9f1358a80ba384a21969e0b4e66a9b17"},
|
||||
{file = "Brotli-1.0.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:85f7912459c67eaab2fb854ed2bc1cc25772b300545fe7ed2dc03954da638649"},
|
||||
{file = "Brotli-1.0.9-cp38-cp38-win32.whl", hash = "sha256:35a3edbe18e876e596553c4007a087f8bcfd538f19bc116917b3c7522fca0429"},
|
||||
{file = "Brotli-1.0.9-cp38-cp38-win_amd64.whl", hash = "sha256:269a5743a393c65db46a7bb982644c67ecba4b8d91b392403ad8a861ba6f495f"},
|
||||
{file = "Brotli-1.0.9-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2aad0e0baa04517741c9bb5b07586c642302e5fb3e75319cb62087bd0995ab19"},
|
||||
{file = "Brotli-1.0.9-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5cb1e18167792d7d21e21365d7650b72d5081ed476123ff7b8cac7f45189c0c7"},
|
||||
{file = "Brotli-1.0.9-cp39-cp39-manylinux1_i686.whl", hash = "sha256:16d528a45c2e1909c2798f27f7bf0a3feec1dc9e50948e738b961618e38b6a7b"},
|
||||
{file = "Brotli-1.0.9-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:56d027eace784738457437df7331965473f2c0da2c70e1a1f6fdbae5402e0389"},
|
||||
{file = "Brotli-1.0.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bf919756d25e4114ace16a8ce91eb340eb57a08e2c6950c3cebcbe3dff2a5e7"},
|
||||
{file = "Brotli-1.0.9-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e4c4e92c14a57c9bd4cb4be678c25369bf7a092d55fd0866f759e425b9660806"},
|
||||
{file = "Brotli-1.0.9-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e48f4234f2469ed012a98f4b7874e7f7e173c167bed4934912a29e03167cf6b1"},
|
||||
{file = "Brotli-1.0.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9ed4c92a0665002ff8ea852353aeb60d9141eb04109e88928026d3c8a9e5433c"},
|
||||
{file = "Brotli-1.0.9-cp39-cp39-win32.whl", hash = "sha256:cfc391f4429ee0a9370aa93d812a52e1fee0f37a81861f4fdd1f4fb28e8547c3"},
|
||||
{file = "Brotli-1.0.9-cp39-cp39-win_amd64.whl", hash = "sha256:854c33dad5ba0fbd6ab69185fec8dab89e13cda6b7d191ba111987df74f38761"},
|
||||
{file = "Brotli-1.0.9-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9749a124280a0ada4187a6cfd1ffd35c350fb3af79c706589d98e088c5044267"},
|
||||
{file = "Brotli-1.0.9-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:73fd30d4ce0ea48010564ccee1a26bfe39323fde05cb34b5863455629db61dc7"},
|
||||
{file = "Brotli-1.0.9-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:02177603aaca36e1fd21b091cb742bb3b305a569e2402f1ca38af471777fb019"},
|
||||
{file = "Brotli-1.0.9-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:76ffebb907bec09ff511bb3acc077695e2c32bc2142819491579a695f77ffd4d"},
|
||||
{file = "Brotli-1.0.9-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b43775532a5904bc938f9c15b77c613cb6ad6fb30990f3b0afaea82797a402d8"},
|
||||
{file = "Brotli-1.0.9-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5bf37a08493232fbb0f8229f1824b366c2fc1d02d64e7e918af40acd15f3e337"},
|
||||
{file = "Brotli-1.0.9-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:330e3f10cd01da535c70d09c4283ba2df5fb78e915bea0a28becad6e2ac010be"},
|
||||
{file = "Brotli-1.0.9-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e1abbeef02962596548382e393f56e4c94acd286bd0c5afba756cffc33670e8a"},
|
||||
{file = "Brotli-1.0.9-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3148362937217b7072cf80a2dcc007f09bb5ecb96dae4617316638194113d5be"},
|
||||
{file = "Brotli-1.0.9-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:336b40348269f9b91268378de5ff44dc6fbaa2268194f85177b53463d313842a"},
|
||||
{file = "Brotli-1.0.9-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b8b09a16a1950b9ef495a0f8b9d0a87599a9d1f179e2d4ac014b2ec831f87e7"},
|
||||
{file = "Brotli-1.0.9-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c8e521a0ce7cf690ca84b8cc2272ddaf9d8a50294fd086da67e517439614c755"},
|
||||
{file = "Brotli-1.0.9.zip", hash = "sha256:4d1b810aa0ed773f81dceda2cc7b403d01057458730e309856356d4ef4188438"},
|
||||
{file = "Brotli-1.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e1140c64812cb9b06c922e77f1c26a75ec5e3f0fb2bf92cc8c58720dec276752"},
|
||||
{file = "Brotli-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c8fd5270e906eef71d4a8d19b7c6a43760c6abcfcc10c9101d14eb2357418de9"},
|
||||
{file = "Brotli-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ae56aca0402a0f9a3431cddda62ad71666ca9d4dc3a10a142b9dce2e3c0cda3"},
|
||||
{file = "Brotli-1.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43ce1b9935bfa1ede40028054d7f48b5469cd02733a365eec8a329ffd342915d"},
|
||||
{file = "Brotli-1.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:7c4855522edb2e6ae7fdb58e07c3ba9111e7621a8956f481c68d5d979c93032e"},
|
||||
{file = "Brotli-1.1.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:38025d9f30cf4634f8309c6874ef871b841eb3c347e90b0851f63d1ded5212da"},
|
||||
{file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e6a904cb26bfefc2f0a6f240bdf5233be78cd2488900a2f846f3c3ac8489ab80"},
|
||||
{file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a37b8f0391212d29b3a91a799c8e4a2855e0576911cdfb2515487e30e322253d"},
|
||||
{file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e84799f09591700a4154154cab9787452925578841a94321d5ee8fb9a9a328f0"},
|
||||
{file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f66b5337fa213f1da0d9000bc8dc0cb5b896b726eefd9c6046f699b169c41b9e"},
|
||||
{file = "Brotli-1.1.0-cp310-cp310-win32.whl", hash = "sha256:be36e3d172dc816333f33520154d708a2657ea63762ec16b62ece02ab5e4daf2"},
|
||||
{file = "Brotli-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:0c6244521dda65ea562d5a69b9a26120769b7a9fb3db2fe9545935ed6735b128"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a3daabb76a78f829cafc365531c972016e4aa8d5b4bf60660ad8ecee19df7ccc"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c8146669223164fc87a7e3de9f81e9423c67a79d6b3447994dfb9c95da16e2d6"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30924eb4c57903d5a7526b08ef4a584acc22ab1ffa085faceb521521d2de32dd"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ceb64bbc6eac5a140ca649003756940f8d6a7c444a68af170b3187623b43bebf"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a469274ad18dc0e4d316eefa616d1d0c2ff9da369af19fa6f3daa4f09671fd61"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:524f35912131cc2cabb00edfd8d573b07f2d9f21fa824bd3fb19725a9cf06327"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5b3cc074004d968722f51e550b41a27be656ec48f8afaeeb45ebf65b561481dd"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:19c116e796420b0cee3da1ccec3b764ed2952ccfcc298b55a10e5610ad7885f9"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:510b5b1bfbe20e1a7b3baf5fed9e9451873559a976c1a78eebaa3b86c57b4265"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a1fd8a29719ccce974d523580987b7f8229aeace506952fa9ce1d53a033873c8"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-win32.whl", hash = "sha256:39da8adedf6942d76dc3e46653e52df937a3c4d6d18fdc94a7c29d263b1f5b50"},
|
||||
{file = "Brotli-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:aac0411d20e345dc0920bdec5548e438e999ff68d77564d5e9463a7ca9d3e7b1"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:316cc9b17edf613ac76b1f1f305d2a748f1b976b033b049a6ecdfd5612c70409"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:caf9ee9a5775f3111642d33b86237b05808dafcd6268faa492250e9b78046eb2"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70051525001750221daa10907c77830bc889cb6d865cc0b813d9db7fefc21451"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7f4bf76817c14aa98cc6697ac02f3972cb8c3da93e9ef16b9c66573a68014f91"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0c5516f0aed654134a2fc936325cc2e642f8a0e096d075209672eb321cff408"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c3020404e0b5eefd7c9485ccf8393cfb75ec38ce75586e046573c9dc29967a0"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4ed11165dd45ce798d99a136808a794a748d5dc38511303239d4e2363c0695dc"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4093c631e96fdd49e0377a9c167bfd75b6d0bad2ace734c6eb20b348bc3ea180"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e4c4629ddad63006efa0ef968c8e4751c5868ff0b1c5c40f76524e894c50248"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:861bf317735688269936f755fa136a99d1ed526883859f86e41a5d43c61d8966"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-win32.whl", hash = "sha256:5f4d5ea15c9382135076d2fb28dde923352fe02951e66935a9efaac8f10e81b0"},
|
||||
{file = "Brotli-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:906bc3a79de8c4ae5b86d3d75a8b77e44404b0f4261714306e3ad248d8ab0951"},
|
||||
{file = "Brotli-1.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a090ca607cbb6a34b0391776f0cb48062081f5f60ddcce5d11838e67a01928d1"},
|
||||
{file = "Brotli-1.1.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2de9d02f5bda03d27ede52e8cfe7b865b066fa49258cbab568720aa5be80a47d"},
|
||||
{file = "Brotli-1.1.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2333e30a5e00fe0fe55903c8832e08ee9c3b1382aacf4db26664a16528d51b4b"},
|
||||
{file = "Brotli-1.1.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4d4a848d1837973bf0f4b5e54e3bec977d99be36a7895c61abb659301b02c112"},
|
||||
{file = "Brotli-1.1.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:fdc3ff3bfccdc6b9cc7c342c03aa2400683f0cb891d46e94b64a197910dc4064"},
|
||||
{file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:5eeb539606f18a0b232d4ba45adccde4125592f3f636a6182b4a8a436548b914"},
|
||||
{file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:fd5f17ff8f14003595ab414e45fce13d073e0762394f957182e69035c9f3d7c2"},
|
||||
{file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:069a121ac97412d1fe506da790b3e69f52254b9df4eb665cd42460c837193354"},
|
||||
{file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:e93dfc1a1165e385cc8239fab7c036fb2cd8093728cbd85097b284d7b99249a2"},
|
||||
{file = "Brotli-1.1.0-cp36-cp36m-win32.whl", hash = "sha256:a599669fd7c47233438a56936988a2478685e74854088ef5293802123b5b2460"},
|
||||
{file = "Brotli-1.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:d143fd47fad1db3d7c27a1b1d66162e855b5d50a89666af46e1679c496e8e579"},
|
||||
{file = "Brotli-1.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:11d00ed0a83fa22d29bc6b64ef636c4552ebafcef57154b4ddd132f5638fbd1c"},
|
||||
{file = "Brotli-1.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f733d788519c7e3e71f0855c96618720f5d3d60c3cb829d8bbb722dddce37985"},
|
||||
{file = "Brotli-1.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:929811df5462e182b13920da56c6e0284af407d1de637d8e536c5cd00a7daf60"},
|
||||
{file = "Brotli-1.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0b63b949ff929fbc2d6d3ce0e924c9b93c9785d877a21a1b678877ffbbc4423a"},
|
||||
{file = "Brotli-1.1.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d192f0f30804e55db0d0e0a35d83a9fead0e9a359a9ed0285dbacea60cc10a84"},
|
||||
{file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f296c40e23065d0d6650c4aefe7470d2a25fffda489bcc3eb66083f3ac9f6643"},
|
||||
{file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:919e32f147ae93a09fe064d77d5ebf4e35502a8df75c29fb05788528e330fe74"},
|
||||
{file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:23032ae55523cc7bccb4f6a0bf368cd25ad9bcdcc1990b64a647e7bbcce9cb5b"},
|
||||
{file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:224e57f6eac61cc449f498cc5f0e1725ba2071a3d4f48d5d9dffba42db196438"},
|
||||
{file = "Brotli-1.1.0-cp37-cp37m-win32.whl", hash = "sha256:587ca6d3cef6e4e868102672d3bd9dc9698c309ba56d41c2b9c85bbb903cdb95"},
|
||||
{file = "Brotli-1.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2954c1c23f81c2eaf0b0717d9380bd348578a94161a65b3a2afc62c86467dd68"},
|
||||
{file = "Brotli-1.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:efa8b278894b14d6da122a72fefcebc28445f2d3f880ac59d46c90f4c13be9a3"},
|
||||
{file = "Brotli-1.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:03d20af184290887bdea3f0f78c4f737d126c74dc2f3ccadf07e54ceca3bf208"},
|
||||
{file = "Brotli-1.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6172447e1b368dcbc458925e5ddaf9113477b0ed542df258d84fa28fc45ceea7"},
|
||||
{file = "Brotli-1.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a743e5a28af5f70f9c080380a5f908d4d21d40e8f0e0c8901604d15cfa9ba751"},
|
||||
{file = "Brotli-1.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0541e747cce78e24ea12d69176f6a7ddb690e62c425e01d31cc065e69ce55b48"},
|
||||
{file = "Brotli-1.1.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cdbc1fc1bc0bff1cef838eafe581b55bfbffaed4ed0318b724d0b71d4d377619"},
|
||||
{file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:890b5a14ce214389b2cc36ce82f3093f96f4cc730c1cffdbefff77a7c71f2a97"},
|
||||
{file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ab4fbee0b2d9098c74f3057b2bc055a8bd92ccf02f65944a241b4349229185a"},
|
||||
{file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:141bd4d93984070e097521ed07e2575b46f817d08f9fa42b16b9b5f27b5ac088"},
|
||||
{file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fce1473f3ccc4187f75b4690cfc922628aed4d3dd013d047f95a9b3919a86596"},
|
||||
{file = "Brotli-1.1.0-cp38-cp38-win32.whl", hash = "sha256:db85ecf4e609a48f4b29055f1e144231b90edc90af7481aa731ba2d059226b1b"},
|
||||
{file = "Brotli-1.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3d7954194c36e304e1523f55d7042c59dc53ec20dd4e9ea9d151f1b62b4415c0"},
|
||||
{file = "Brotli-1.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5fb2ce4b8045c78ebbc7b8f3c15062e435d47e7393cc57c25115cfd49883747a"},
|
||||
{file = "Brotli-1.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7905193081db9bfa73b1219140b3d315831cbff0d8941f22da695832f0dd188f"},
|
||||
{file = "Brotli-1.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a77def80806c421b4b0af06f45d65a136e7ac0bdca3c09d9e2ea4e515367c7e9"},
|
||||
{file = "Brotli-1.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dadd1314583ec0bf2d1379f7008ad627cd6336625d6679cf2f8e67081b83acf"},
|
||||
{file = "Brotli-1.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:901032ff242d479a0efa956d853d16875d42157f98951c0230f69e69f9c09bac"},
|
||||
{file = "Brotli-1.1.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:22fc2a8549ffe699bfba2256ab2ed0421a7b8fadff114a3d201794e45a9ff578"},
|
||||
{file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ae15b066e5ad21366600ebec29a7ccbc86812ed267e4b28e860b8ca16a2bc474"},
|
||||
{file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:949f3b7c29912693cee0afcf09acd6ebc04c57af949d9bf77d6101ebb61e388c"},
|
||||
{file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:89f4988c7203739d48c6f806f1e87a1d96e0806d44f0fba61dba81392c9e474d"},
|
||||
{file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:de6551e370ef19f8de1807d0a9aa2cdfdce2e85ce88b122fe9f6b2b076837e59"},
|
||||
{file = "Brotli-1.1.0-cp39-cp39-win32.whl", hash = "sha256:f0d8a7a6b5983c2496e364b969f0e526647a06b075d034f3297dc66f3b360c64"},
|
||||
{file = "Brotli-1.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:cdad5b9014d83ca68c25d2e9444e28e967ef16e80f6b436918c700c117a85467"},
|
||||
{file = "Brotli-1.1.0.tar.gz", hash = "sha256:81de08ac11bcb85841e440c13611c00b67d3bf82698314928d0b676362546724"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "brotlicffi"
|
||||
version = "1.1.0.0"
|
||||
description = "Python CFFI bindings to the Brotli library"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "brotlicffi-1.1.0.0-cp37-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9b7ae6bd1a3f0df532b6d67ff674099a96d22bc0948955cb338488c31bfb8851"},
|
||||
{file = "brotlicffi-1.1.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19ffc919fa4fc6ace69286e0a23b3789b4219058313cf9b45625016bf7ff996b"},
|
||||
{file = "brotlicffi-1.1.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9feb210d932ffe7798ee62e6145d3a757eb6233aa9a4e7db78dd3690d7755814"},
|
||||
{file = "brotlicffi-1.1.0.0-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84763dbdef5dd5c24b75597a77e1b30c66604725707565188ba54bab4f114820"},
|
||||
{file = "brotlicffi-1.1.0.0-cp37-abi3-win32.whl", hash = "sha256:1b12b50e07c3911e1efa3a8971543e7648100713d4e0971b13631cce22c587eb"},
|
||||
{file = "brotlicffi-1.1.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:994a4f0681bb6c6c3b0925530a1926b7a189d878e6e5e38fae8efa47c5d9c613"},
|
||||
{file = "brotlicffi-1.1.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2e4aeb0bd2540cb91b069dbdd54d458da8c4334ceaf2d25df2f4af576d6766ca"},
|
||||
{file = "brotlicffi-1.1.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b7b0033b0d37bb33009fb2fef73310e432e76f688af76c156b3594389d81391"},
|
||||
{file = "brotlicffi-1.1.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54a07bb2374a1eba8ebb52b6fafffa2afd3c4df85ddd38fcc0511f2bb387c2a8"},
|
||||
{file = "brotlicffi-1.1.0.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7901a7dc4b88f1c1475de59ae9be59799db1007b7d059817948d8e4f12e24e35"},
|
||||
{file = "brotlicffi-1.1.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ce01c7316aebc7fce59da734286148b1d1b9455f89cf2c8a4dfce7d41db55c2d"},
|
||||
{file = "brotlicffi-1.1.0.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:246f1d1a90279bb6069de3de8d75a8856e073b8ff0b09dcca18ccc14cec85979"},
|
||||
{file = "brotlicffi-1.1.0.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc4bc5d82bc56ebd8b514fb8350cfac4627d6b0743382e46d033976a5f80fab6"},
|
||||
{file = "brotlicffi-1.1.0.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37c26ecb14386a44b118ce36e546ce307f4810bc9598a6e6cb4f7fca725ae7e6"},
|
||||
{file = "brotlicffi-1.1.0.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca72968ae4eaf6470498d5c2887073f7efe3b1e7d7ec8be11a06a79cc810e990"},
|
||||
{file = "brotlicffi-1.1.0.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:add0de5b9ad9e9aa293c3aa4e9deb2b61e99ad6c1634e01d01d98c03e6a354cc"},
|
||||
{file = "brotlicffi-1.1.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9b6068e0f3769992d6b622a1cd2e7835eae3cf8d9da123d7f51ca9c1e9c333e5"},
|
||||
{file = "brotlicffi-1.1.0.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8557a8559509b61e65083f8782329188a250102372576093c88930c875a69838"},
|
||||
{file = "brotlicffi-1.1.0.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a7ae37e5d79c5bdfb5b4b99f2715a6035e6c5bf538c3746abc8e26694f92f33"},
|
||||
{file = "brotlicffi-1.1.0.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:391151ec86bb1c683835980f4816272a87eaddc46bb91cbf44f62228b84d8cca"},
|
||||
{file = "brotlicffi-1.1.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:2f3711be9290f0453de8eed5275d93d286abe26b08ab4a35d7452caa1fef532f"},
|
||||
{file = "brotlicffi-1.1.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1a807d760763e398bbf2c6394ae9da5815901aa93ee0a37bca5efe78d4ee3171"},
|
||||
{file = "brotlicffi-1.1.0.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa8ca0623b26c94fccc3a1fdd895be1743b838f3917300506d04aa3346fd2a14"},
|
||||
{file = "brotlicffi-1.1.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3de0cf28a53a3238b252aca9fed1593e9d36c1d116748013339f0949bfc84112"},
|
||||
{file = "brotlicffi-1.1.0.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6be5ec0e88a4925c91f3dea2bb0013b3a2accda6f77238f76a34a1ea532a1cb0"},
|
||||
{file = "brotlicffi-1.1.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d9eb71bb1085d996244439154387266fd23d6ad37161f6f52f1cd41dd95a3808"},
|
||||
{file = "brotlicffi-1.1.0.0.tar.gz", hash = "sha256:b77827a689905143f87915310b93b273ab17888fd43ef350d4832c4a71083c13"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
cffi = ">=1.0.0"
|
||||
|
||||
[[package]]
|
||||
name = "cachetools"
|
||||
version = "5.3.1"
|
||||
|
@ -205,16 +246,93 @@ files = [
|
|||
{file = "cachetools-5.3.1.tar.gz", hash = "sha256:dce83f2d9b4e1f732a8cd44af8e8fab2dbe46201467fc98b3ef8f269092bf62b"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cffi"
|
||||
version = "1.15.1"
|
||||
description = "Foreign Function Interface for Python calling C code."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"},
|
||||
{file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"},
|
||||
{file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"},
|
||||
{file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"},
|
||||
{file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"},
|
||||
{file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"},
|
||||
{file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"},
|
||||
{file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
pycparser = "*"
|
||||
|
||||
[[package]]
|
||||
name = "click"
|
||||
version = "8.1.6"
|
||||
version = "8.1.7"
|
||||
description = "Composable command line interface toolkit"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "click-8.1.6-py3-none-any.whl", hash = "sha256:fa244bb30b3b5ee2cae3da8f55c9e5e0c0e86093306301fb418eb9dc40fbded5"},
|
||||
{file = "click-8.1.6.tar.gz", hash = "sha256:48ee849951919527a045bfe3bf7baa8a959c423134e1a5b98c05c20ba75a1cbd"},
|
||||
{file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
|
||||
{file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
@ -275,14 +393,14 @@ graph = ["objgraph (>=1.7.2)"]
|
|||
|
||||
[[package]]
|
||||
name = "flask"
|
||||
version = "2.3.2"
|
||||
version = "2.3.3"
|
||||
description = "A simple framework for building complex web applications."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "Flask-2.3.2-py3-none-any.whl", hash = "sha256:77fd4e1249d8c9923de34907236b747ced06e5467ecac1a7bb7115ae0e9670b0"},
|
||||
{file = "Flask-2.3.2.tar.gz", hash = "sha256:8c2f9abd47a9e8df7f0c3f091ce9497d011dc3b31effcf4c85a6e2b50f4114ef"},
|
||||
{file = "flask-2.3.3-py3-none-any.whl", hash = "sha256:f69fcd559dc907ed196ab9df0e48471709175e696d6e698dd4dbe940f96ce66b"},
|
||||
{file = "flask-2.3.3.tar.gz", hash = "sha256:09c347a92aa7ff4a8e7f3206795f30d826654baf38b873d0744cd571ca609efc"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
@ -291,7 +409,7 @@ click = ">=8.1.3"
|
|||
importlib-metadata = {version = ">=3.6.0", markers = "python_version < \"3.10\""}
|
||||
itsdangerous = ">=2.1.2"
|
||||
Jinja2 = ">=3.1.2"
|
||||
Werkzeug = ">=2.3.3"
|
||||
Werkzeug = ">=2.3.7"
|
||||
|
||||
[package.extras]
|
||||
async = ["asgiref (>=3.2)"]
|
||||
|
@ -330,18 +448,19 @@ Flask = "*"
|
|||
|
||||
[[package]]
|
||||
name = "flask-compress"
|
||||
version = "1.13"
|
||||
version = "1.14"
|
||||
description = "Compress responses in your Flask app with gzip, deflate or brotli."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "Flask-Compress-1.13.tar.gz", hash = "sha256:ee96f18bf9b00f2deb4e3406ca4a05093aa80e2ef0578525a3b4d32ecdff129d"},
|
||||
{file = "Flask_Compress-1.13-py3-none-any.whl", hash = "sha256:1128f71fbd788393ce26830c51f8b5a1a7a4d085e79a21a5cddf4c057dcd559b"},
|
||||
{file = "Flask-Compress-1.14.tar.gz", hash = "sha256:e46528f37b91857012be38e24e65db1a248662c3dc32ee7808b5986bf1d123ee"},
|
||||
{file = "Flask_Compress-1.14-py3-none-any.whl", hash = "sha256:b86c9808f0f38ea2246c9730972cf978f2cdf6a9a1a69102ba81e07891e6b26c"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
brotli = "*"
|
||||
brotli = {version = "*", markers = "platform_python_implementation != \"PyPy\""}
|
||||
brotlicffi = {version = "*", markers = "platform_python_implementation == \"PyPy\""}
|
||||
flask = "*"
|
||||
|
||||
[[package]]
|
||||
|
@ -362,14 +481,14 @@ Werkzeug = ">=1.0.1"
|
|||
|
||||
[[package]]
|
||||
name = "flask-migrate"
|
||||
version = "4.0.4"
|
||||
version = "4.0.5"
|
||||
description = "SQLAlchemy database migrations for Flask applications using Alembic."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "Flask-Migrate-4.0.4.tar.gz", hash = "sha256:73293d40b10ac17736e715b377e7b7bde474cb8105165d77474df4c3619b10b3"},
|
||||
{file = "Flask_Migrate-4.0.4-py3-none-any.whl", hash = "sha256:77580f27ab39bc68be4906a43c56d7674b45075bc4f883b1d0b985db5164d58f"},
|
||||
{file = "Flask-Migrate-4.0.5.tar.gz", hash = "sha256:d3f437a8b5f3849d1bb1b60e1b818efc564c66e3fefe90b62e5db08db295e1b1"},
|
||||
{file = "Flask_Migrate-4.0.5-py3-none-any.whl", hash = "sha256:613a2df703998e78716cace68cd83972960834424457f5b67f56e74fff950aef"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
@ -379,19 +498,19 @@ Flask-SQLAlchemy = ">=1.0"
|
|||
|
||||
[[package]]
|
||||
name = "flask-sqlalchemy"
|
||||
version = "3.0.5"
|
||||
version = "3.1.1"
|
||||
description = "Add SQLAlchemy support to your Flask application."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "flask_sqlalchemy-3.0.5-py3-none-any.whl", hash = "sha256:cabb6600ddd819a9f859f36515bb1bd8e7dbf30206cc679d2b081dff9e383283"},
|
||||
{file = "flask_sqlalchemy-3.0.5.tar.gz", hash = "sha256:c5765e58ca145401b52106c0f46178569243c5da25556be2c231ecc60867c5b1"},
|
||||
{file = "flask_sqlalchemy-3.1.1-py3-none-any.whl", hash = "sha256:4ba4be7f419dc72f4efd8802d69974803c37259dd42f3913b0dcf75c9447e0a0"},
|
||||
{file = "flask_sqlalchemy-3.1.1.tar.gz", hash = "sha256:e4b68bb881802dda1a7d878b2fc84c06d1ee57fb40b874d3dc97dabfa36b8312"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
flask = ">=2.2.5"
|
||||
sqlalchemy = ">=1.4.18"
|
||||
sqlalchemy = ">=2.0.16"
|
||||
|
||||
[[package]]
|
||||
name = "greenlet"
|
||||
|
@ -469,18 +588,18 @@ test = ["objgraph", "psutil"]
|
|||
|
||||
[[package]]
|
||||
name = "gunicorn"
|
||||
version = "20.1.0"
|
||||
version = "21.2.0"
|
||||
description = "WSGI HTTP Server for UNIX"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
{file = "gunicorn-20.1.0-py3-none-any.whl", hash = "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e"},
|
||||
{file = "gunicorn-20.1.0.tar.gz", hash = "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"},
|
||||
{file = "gunicorn-21.2.0-py3-none-any.whl", hash = "sha256:3213aa5e8c24949e792bcacfc176fef362e7aac80b76c56f6b5122bf350722f0"},
|
||||
{file = "gunicorn-21.2.0.tar.gz", hash = "sha256:88ec8bff1d634f98e61b9f65bc4bf3cd918a90806c6f5c48bc5603849ec81033"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
setuptools = ">=3.0"
|
||||
packaging = "*"
|
||||
|
||||
[package.extras]
|
||||
eventlet = ["eventlet (>=0.24.1)"]
|
||||
|
@ -510,22 +629,22 @@ testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs
|
|||
|
||||
[[package]]
|
||||
name = "importlib-resources"
|
||||
version = "6.0.0"
|
||||
version = "6.1.0"
|
||||
description = "Read resources from Python packages"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "importlib_resources-6.0.0-py3-none-any.whl", hash = "sha256:d952faee11004c045f785bb5636e8f885bed30dc3c940d5d42798a2a4541c185"},
|
||||
{file = "importlib_resources-6.0.0.tar.gz", hash = "sha256:4cf94875a8368bd89531a756df9a9ebe1f150e0f885030b461237bc7f2d905f2"},
|
||||
{file = "importlib_resources-6.1.0-py3-none-any.whl", hash = "sha256:aa50258bbfa56d4e33fbd8aa3ef48ded10d1735f11532b8df95388cc6bdb7e83"},
|
||||
{file = "importlib_resources-6.1.0.tar.gz", hash = "sha256:9d48dcccc213325e810fd723e7fbb45ccb39f6cf5c31f00cf2b965f5f10f3cb9"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""}
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
|
||||
testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff"]
|
||||
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"]
|
||||
testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff", "zipp (>=3.17)"]
|
||||
|
||||
[[package]]
|
||||
name = "isort"
|
||||
|
@ -727,6 +846,22 @@ files = [
|
|||
{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]]
|
||||
name = "mccabe"
|
||||
version = "0.7.0"
|
||||
|
@ -871,20 +1006,32 @@ files = [
|
|||
docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"]
|
||||
test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "pycparser"
|
||||
version = "2.21"
|
||||
description = "C parser in Python"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
files = [
|
||||
{file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"},
|
||||
{file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pylint"
|
||||
version = "2.17.5"
|
||||
version = "2.17.6"
|
||||
description = "python code static checker"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7.2"
|
||||
files = [
|
||||
{file = "pylint-2.17.5-py3-none-any.whl", hash = "sha256:73995fb8216d3bed149c8d51bba25b2c52a8251a2c8ac846ec668ce38fab5413"},
|
||||
{file = "pylint-2.17.5.tar.gz", hash = "sha256:f7b601cbc06fef7e62a754e2b41294c2aa31f1cb659624b9a85bcba29eaf8252"},
|
||||
{file = "pylint-2.17.6-py3-none-any.whl", hash = "sha256:18a1412e873caf8ffb56b760ce1b5643675af23e6173a247b502406b24c716af"},
|
||||
{file = "pylint-2.17.6.tar.gz", hash = "sha256:be928cce5c76bf9acdc65ad01447a1e0b1a7bccffc609fb7fc40f2513045bd05"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
astroid = ">=2.15.6,<=2.17.0-dev0"
|
||||
astroid = ">=2.15.7,<=2.17.0-dev0"
|
||||
colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""}
|
||||
dill = [
|
||||
{version = ">=0.2", markers = "python_version < \"3.11\""},
|
||||
|
@ -903,14 +1050,14 @@ testutils = ["gitpython (>3)"]
|
|||
|
||||
[[package]]
|
||||
name = "python-dotenv"
|
||||
version = "0.21.1"
|
||||
version = "1.0.0"
|
||||
description = "Read key-value pairs from a .env file and set them as environment variables"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "python-dotenv-0.21.1.tar.gz", hash = "sha256:1c93de8f636cde3ce377292818d0e440b6e45a82f215c3744979151fa8151c49"},
|
||||
{file = "python_dotenv-0.21.1-py3-none-any.whl", hash = "sha256:41e12e0318bebc859fcc4d97d4db8d20ad21721a6aa5047dd59f090391cb549a"},
|
||||
{file = "python-dotenv-1.0.0.tar.gz", hash = "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba"},
|
||||
{file = "python_dotenv-1.0.0-py3-none-any.whl", hash = "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
|
@ -967,71 +1114,152 @@ files = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "setuptools"
|
||||
version = "68.0.0"
|
||||
description = "Easily download, build, install, upgrade, and uninstall Python packages"
|
||||
name = "regex"
|
||||
version = "2023.8.8"
|
||||
description = "Alternative regular expression module, to replace re."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "setuptools-68.0.0-py3-none-any.whl", hash = "sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f"},
|
||||
{file = "setuptools-68.0.0.tar.gz", hash = "sha256:baf1fdb41c6da4cd2eae722e135500da913332ab3f2f5c7d33af9b492acb5235"},
|
||||
{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.extras]
|
||||
docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
|
||||
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
|
||||
testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
|
||||
|
||||
[[package]]
|
||||
name = "sqlalchemy"
|
||||
version = "2.0.19"
|
||||
version = "2.0.21"
|
||||
description = "Database Abstraction Library"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "SQLAlchemy-2.0.19-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9deaae357edc2091a9ed5d25e9ee8bba98bcfae454b3911adeaf159c2e9ca9e3"},
|
||||
{file = "SQLAlchemy-2.0.19-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0bf0fd65b50a330261ec7fe3d091dfc1c577483c96a9fa1e4323e932961aa1b5"},
|
||||
{file = "SQLAlchemy-2.0.19-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d90ccc15ba1baa345796a8fb1965223ca7ded2d235ccbef80a47b85cea2d71a"},
|
||||
{file = "SQLAlchemy-2.0.19-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb4e688f6784427e5f9479d1a13617f573de8f7d4aa713ba82813bcd16e259d1"},
|
||||
{file = "SQLAlchemy-2.0.19-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:584f66e5e1979a7a00f4935015840be627e31ca29ad13f49a6e51e97a3fb8cae"},
|
||||
{file = "SQLAlchemy-2.0.19-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2c69ce70047b801d2aba3e5ff3cba32014558966109fecab0c39d16c18510f15"},
|
||||
{file = "SQLAlchemy-2.0.19-cp310-cp310-win32.whl", hash = "sha256:96f0463573469579d32ad0c91929548d78314ef95c210a8115346271beeeaaa2"},
|
||||
{file = "SQLAlchemy-2.0.19-cp310-cp310-win_amd64.whl", hash = "sha256:22bafb1da60c24514c141a7ff852b52f9f573fb933b1e6b5263f0daa28ce6db9"},
|
||||
{file = "SQLAlchemy-2.0.19-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d6894708eeb81f6d8193e996257223b6bb4041cb05a17cd5cf373ed836ef87a2"},
|
||||
{file = "SQLAlchemy-2.0.19-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8f2afd1aafded7362b397581772c670f20ea84d0a780b93a1a1529da7c3d369"},
|
||||
{file = "SQLAlchemy-2.0.19-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15afbf5aa76f2241184c1d3b61af1a72ba31ce4161013d7cb5c4c2fca04fd6e"},
|
||||
{file = "SQLAlchemy-2.0.19-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fc05b59142445a4efb9c1fd75c334b431d35c304b0e33f4fa0ff1ea4890f92e"},
|
||||
{file = "SQLAlchemy-2.0.19-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5831138f0cc06b43edf5f99541c64adf0ab0d41f9a4471fd63b54ae18399e4de"},
|
||||
{file = "SQLAlchemy-2.0.19-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3afa8a21a9046917b3a12ffe016ba7ebe7a55a6fc0c7d950beb303c735c3c3ad"},
|
||||
{file = "SQLAlchemy-2.0.19-cp311-cp311-win32.whl", hash = "sha256:c896d4e6ab2eba2afa1d56be3d0b936c56d4666e789bfc59d6ae76e9fcf46145"},
|
||||
{file = "SQLAlchemy-2.0.19-cp311-cp311-win_amd64.whl", hash = "sha256:024d2f67fb3ec697555e48caeb7147cfe2c08065a4f1a52d93c3d44fc8e6ad1c"},
|
||||
{file = "SQLAlchemy-2.0.19-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:89bc2b374ebee1a02fd2eae6fd0570b5ad897ee514e0f84c5c137c942772aa0c"},
|
||||
{file = "SQLAlchemy-2.0.19-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd4d410a76c3762511ae075d50f379ae09551d92525aa5bb307f8343bf7c2c12"},
|
||||
{file = "SQLAlchemy-2.0.19-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f469f15068cd8351826df4080ffe4cc6377c5bf7d29b5a07b0e717dddb4c7ea2"},
|
||||
{file = "SQLAlchemy-2.0.19-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:cda283700c984e699e8ef0fcc5c61f00c9d14b6f65a4f2767c97242513fcdd84"},
|
||||
{file = "SQLAlchemy-2.0.19-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:43699eb3f80920cc39a380c159ae21c8a8924fe071bccb68fc509e099420b148"},
|
||||
{file = "SQLAlchemy-2.0.19-cp37-cp37m-win32.whl", hash = "sha256:61ada5831db36d897e28eb95f0f81814525e0d7927fb51145526c4e63174920b"},
|
||||
{file = "SQLAlchemy-2.0.19-cp37-cp37m-win_amd64.whl", hash = "sha256:57d100a421d9ab4874f51285c059003292433c648df6abe6c9c904e5bd5b0828"},
|
||||
{file = "SQLAlchemy-2.0.19-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:16a310f5bc75a5b2ce7cb656d0e76eb13440b8354f927ff15cbaddd2523ee2d1"},
|
||||
{file = "SQLAlchemy-2.0.19-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cf7b5e3856cbf1876da4e9d9715546fa26b6e0ba1a682d5ed2fc3ca4c7c3ec5b"},
|
||||
{file = "SQLAlchemy-2.0.19-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e7b69d9ced4b53310a87117824b23c509c6fc1f692aa7272d47561347e133b6"},
|
||||
{file = "SQLAlchemy-2.0.19-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f9eb4575bfa5afc4b066528302bf12083da3175f71b64a43a7c0badda2be365"},
|
||||
{file = "SQLAlchemy-2.0.19-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6b54d1ad7a162857bb7c8ef689049c7cd9eae2f38864fc096d62ae10bc100c7d"},
|
||||
{file = "SQLAlchemy-2.0.19-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5d6afc41ca0ecf373366fd8e10aee2797128d3ae45eb8467b19da4899bcd1ee0"},
|
||||
{file = "SQLAlchemy-2.0.19-cp38-cp38-win32.whl", hash = "sha256:430614f18443b58ceb9dedec323ecddc0abb2b34e79d03503b5a7579cd73a531"},
|
||||
{file = "SQLAlchemy-2.0.19-cp38-cp38-win_amd64.whl", hash = "sha256:eb60699de43ba1a1f77363f563bb2c652f7748127ba3a774f7cf2c7804aa0d3d"},
|
||||
{file = "SQLAlchemy-2.0.19-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a752b7a9aceb0ba173955d4f780c64ee15a1a991f1c52d307d6215c6c73b3a4c"},
|
||||
{file = "SQLAlchemy-2.0.19-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7351c05db355da112e056a7b731253cbeffab9dfdb3be1e895368513c7d70106"},
|
||||
{file = "SQLAlchemy-2.0.19-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa51ce4aea583b0c6b426f4b0563d3535c1c75986c4373a0987d84d22376585b"},
|
||||
{file = "SQLAlchemy-2.0.19-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae7473a67cd82a41decfea58c0eac581209a0aa30f8bc9190926fbf628bb17f7"},
|
||||
{file = "SQLAlchemy-2.0.19-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:851a37898a8a39783aab603c7348eb5b20d83c76a14766a43f56e6ad422d1ec8"},
|
||||
{file = "SQLAlchemy-2.0.19-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:539010665c90e60c4a1650afe4ab49ca100c74e6aef882466f1de6471d414be7"},
|
||||
{file = "SQLAlchemy-2.0.19-cp39-cp39-win32.whl", hash = "sha256:f82c310ddf97b04e1392c33cf9a70909e0ae10a7e2ddc1d64495e3abdc5d19fb"},
|
||||
{file = "SQLAlchemy-2.0.19-cp39-cp39-win_amd64.whl", hash = "sha256:8e712cfd2e07b801bc6b60fdf64853bc2bd0af33ca8fa46166a23fe11ce0dbb0"},
|
||||
{file = "SQLAlchemy-2.0.19-py3-none-any.whl", hash = "sha256:314145c1389b021a9ad5aa3a18bac6f5d939f9087d7fc5443be28cba19d2c972"},
|
||||
{file = "SQLAlchemy-2.0.19.tar.gz", hash = "sha256:77a14fa20264af73ddcdb1e2b9c5a829b8cc6b8304d0f093271980e36c200a3f"},
|
||||
{file = "SQLAlchemy-2.0.21-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1e7dc99b23e33c71d720c4ae37ebb095bebebbd31a24b7d99dfc4753d2803ede"},
|
||||
{file = "SQLAlchemy-2.0.21-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7f0c4ee579acfe6c994637527c386d1c22eb60bc1c1d36d940d8477e482095d4"},
|
||||
{file = "SQLAlchemy-2.0.21-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f7d57a7e140efe69ce2d7b057c3f9a595f98d0bbdfc23fd055efdfbaa46e3a5"},
|
||||
{file = "SQLAlchemy-2.0.21-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ca38746eac23dd7c20bec9278d2058c7ad662b2f1576e4c3dbfcd7c00cc48fa"},
|
||||
{file = "SQLAlchemy-2.0.21-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3cf229704074bce31f7f47d12883afee3b0a02bb233a0ba45ddbfe542939cca4"},
|
||||
{file = "SQLAlchemy-2.0.21-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fb87f763b5d04a82ae84ccff25554ffd903baafba6698e18ebaf32561f2fe4aa"},
|
||||
{file = "SQLAlchemy-2.0.21-cp310-cp310-win32.whl", hash = "sha256:89e274604abb1a7fd5c14867a412c9d49c08ccf6ce3e1e04fffc068b5b6499d4"},
|
||||
{file = "SQLAlchemy-2.0.21-cp310-cp310-win_amd64.whl", hash = "sha256:e36339a68126ffb708dc6d1948161cea2a9e85d7d7b0c54f6999853d70d44430"},
|
||||
{file = "SQLAlchemy-2.0.21-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bf8eebccc66829010f06fbd2b80095d7872991bfe8415098b9fe47deaaa58063"},
|
||||
{file = "SQLAlchemy-2.0.21-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b977bfce15afa53d9cf6a632482d7968477625f030d86a109f7bdfe8ce3c064a"},
|
||||
{file = "SQLAlchemy-2.0.21-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ff3dc2f60dbf82c9e599c2915db1526d65415be323464f84de8db3e361ba5b9"},
|
||||
{file = "SQLAlchemy-2.0.21-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44ac5c89b6896f4740e7091f4a0ff2e62881da80c239dd9408f84f75a293dae9"},
|
||||
{file = "SQLAlchemy-2.0.21-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:87bf91ebf15258c4701d71dcdd9c4ba39521fb6a37379ea68088ce8cd869b446"},
|
||||
{file = "SQLAlchemy-2.0.21-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b69f1f754d92eb1cc6b50938359dead36b96a1dcf11a8670bff65fd9b21a4b09"},
|
||||
{file = "SQLAlchemy-2.0.21-cp311-cp311-win32.whl", hash = "sha256:af520a730d523eab77d754f5cf44cc7dd7ad2d54907adeb3233177eeb22f271b"},
|
||||
{file = "SQLAlchemy-2.0.21-cp311-cp311-win_amd64.whl", hash = "sha256:141675dae56522126986fa4ca713739d00ed3a6f08f3c2eb92c39c6dfec463ce"},
|
||||
{file = "SQLAlchemy-2.0.21-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7614f1eab4336df7dd6bee05bc974f2b02c38d3d0c78060c5faa4cd1ca2af3b8"},
|
||||
{file = "SQLAlchemy-2.0.21-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d59cb9e20d79686aa473e0302e4a82882d7118744d30bb1dfb62d3c47141b3ec"},
|
||||
{file = "SQLAlchemy-2.0.21-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a95aa0672e3065d43c8aa80080cdd5cc40fe92dc873749e6c1cf23914c4b83af"},
|
||||
{file = "SQLAlchemy-2.0.21-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8c323813963b2503e54d0944813cd479c10c636e3ee223bcbd7bd478bf53c178"},
|
||||
{file = "SQLAlchemy-2.0.21-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:419b1276b55925b5ac9b4c7044e999f1787c69761a3c9756dec6e5c225ceca01"},
|
||||
{file = "SQLAlchemy-2.0.21-cp37-cp37m-win32.whl", hash = "sha256:4615623a490e46be85fbaa6335f35cf80e61df0783240afe7d4f544778c315a9"},
|
||||
{file = "SQLAlchemy-2.0.21-cp37-cp37m-win_amd64.whl", hash = "sha256:cca720d05389ab1a5877ff05af96551e58ba65e8dc65582d849ac83ddde3e231"},
|
||||
{file = "SQLAlchemy-2.0.21-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b4eae01faee9f2b17f08885e3f047153ae0416648f8e8c8bd9bc677c5ce64be9"},
|
||||
{file = "SQLAlchemy-2.0.21-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3eb7c03fe1cd3255811cd4e74db1ab8dca22074d50cd8937edf4ef62d758cdf4"},
|
||||
{file = "SQLAlchemy-2.0.21-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2d494b6a2a2d05fb99f01b84cc9af9f5f93bf3e1e5dbdafe4bed0c2823584c1"},
|
||||
{file = "SQLAlchemy-2.0.21-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b19ae41ef26c01a987e49e37c77b9ad060c59f94d3b3efdfdbf4f3daaca7b5fe"},
|
||||
{file = "SQLAlchemy-2.0.21-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:fc6b15465fabccc94bf7e38777d665b6a4f95efd1725049d6184b3a39fd54880"},
|
||||
{file = "SQLAlchemy-2.0.21-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:014794b60d2021cc8ae0f91d4d0331fe92691ae5467a00841f7130fe877b678e"},
|
||||
{file = "SQLAlchemy-2.0.21-cp38-cp38-win32.whl", hash = "sha256:0268256a34806e5d1c8f7ee93277d7ea8cc8ae391f487213139018b6805aeaf6"},
|
||||
{file = "SQLAlchemy-2.0.21-cp38-cp38-win_amd64.whl", hash = "sha256:73c079e21d10ff2be54a4699f55865d4b275fd6c8bd5d90c5b1ef78ae0197301"},
|
||||
{file = "SQLAlchemy-2.0.21-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:785e2f2c1cb50d0a44e2cdeea5fd36b5bf2d79c481c10f3a88a8be4cfa2c4615"},
|
||||
{file = "SQLAlchemy-2.0.21-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c111cd40910ffcb615b33605fc8f8e22146aeb7933d06569ac90f219818345ef"},
|
||||
{file = "SQLAlchemy-2.0.21-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9cba4e7369de663611ce7460a34be48e999e0bbb1feb9130070f0685e9a6b66"},
|
||||
{file = "SQLAlchemy-2.0.21-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50a69067af86ec7f11a8e50ba85544657b1477aabf64fa447fd3736b5a0a4f67"},
|
||||
{file = "SQLAlchemy-2.0.21-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ccb99c3138c9bde118b51a289d90096a3791658da9aea1754667302ed6564f6e"},
|
||||
{file = "SQLAlchemy-2.0.21-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:513fd5b6513d37e985eb5b7ed89da5fd9e72354e3523980ef00d439bc549c9e9"},
|
||||
{file = "SQLAlchemy-2.0.21-cp39-cp39-win32.whl", hash = "sha256:f9fefd6298433b6e9188252f3bff53b9ff0443c8fde27298b8a2b19f6617eeb9"},
|
||||
{file = "SQLAlchemy-2.0.21-cp39-cp39-win_amd64.whl", hash = "sha256:2e617727fe4091cedb3e4409b39368f424934c7faa78171749f704b49b4bb4ce"},
|
||||
{file = "SQLAlchemy-2.0.21-py3-none-any.whl", hash = "sha256:ea7da25ee458d8f404b93eb073116156fd7d8c2a776d8311534851f28277b4ce"},
|
||||
{file = "SQLAlchemy-2.0.21.tar.gz", hash = "sha256:05b971ab1ac2994a14c56b35eaaa91f86ba080e9ad481b20d99d77f381bb6258"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
@ -1039,7 +1267,7 @@ greenlet = {version = "!=0.4.17", markers = "platform_machine == \"aarch64\" or
|
|||
typing-extensions = ">=4.2.0"
|
||||
|
||||
[package.extras]
|
||||
aiomysql = ["aiomysql", "greenlet (!=0.4.17)"]
|
||||
aiomysql = ["aiomysql (>=0.2.0)", "greenlet (!=0.4.17)"]
|
||||
aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing-extensions (!=3.10.0.1)"]
|
||||
asyncio = ["greenlet (!=0.4.17)"]
|
||||
asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (!=0.4.17)"]
|
||||
|
@ -1088,14 +1316,14 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.7.1"
|
||||
description = "Backported and Experimental Type Hints for Python 3.7+"
|
||||
version = "4.8.0"
|
||||
description = "Backported and Experimental Type Hints for Python 3.8+"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"},
|
||||
{file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"},
|
||||
{file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"},
|
||||
{file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1112,14 +1340,14 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "werkzeug"
|
||||
version = "2.3.6"
|
||||
version = "2.3.7"
|
||||
description = "The comprehensive WSGI web application library."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "Werkzeug-2.3.6-py3-none-any.whl", hash = "sha256:935539fa1413afbb9195b24880778422ed620c0fc09670945185cce4d91a8890"},
|
||||
{file = "Werkzeug-2.3.6.tar.gz", hash = "sha256:98c774df2f91b05550078891dee5f0eb0cb797a522c757a2452b9cee5b202330"},
|
||||
{file = "werkzeug-2.3.7-py3-none-any.whl", hash = "sha256:effc12dba7f3bd72e605ce49807bbe692bd729c3bb122a3b91747a6ae77df528"},
|
||||
{file = "werkzeug-2.3.7.tar.gz", hash = "sha256:2b8c0e447b4b9dbcc85dd97b6eeb4dcbaf6c8b6c3be0bd654e25553e0a2157d8"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
@ -1215,21 +1443,21 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "zipp"
|
||||
version = "3.16.2"
|
||||
version = "3.17.0"
|
||||
description = "Backport of pathlib-compatible object wrapper for zip files"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "zipp-3.16.2-py3-none-any.whl", hash = "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0"},
|
||||
{file = "zipp-3.16.2.tar.gz", hash = "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147"},
|
||||
{file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"},
|
||||
{file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
|
||||
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"]
|
||||
testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"]
|
||||
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.8"
|
||||
content-hash = "96ec0d1f7b512afb05455262fa2de8c4f862bf68fdae513f8552dc30c6e5ab49"
|
||||
content-hash = "f3ff236ae81d76796722dcd183466f483b6d5aba6dbfcffc145747aa0bb36087"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[tool.poetry]
|
||||
name = "OnlyLegs"
|
||||
version = "0.1.5"
|
||||
version = "0.1.7"
|
||||
repository = "https://github.com/Fluffy-Bean/onlylegs"
|
||||
license = "MIT"
|
||||
readme = "README.md"
|
||||
|
@ -16,8 +16,8 @@ Flask-Compress = "^1.13"
|
|||
Flask-Caching = "1.10.1"
|
||||
Flask-Assets = "^2.0"
|
||||
Flask-Login = "^0.6.2"
|
||||
python-dotenv = "^0.21.0"
|
||||
gunicorn = "^20.1.0"
|
||||
python-dotenv = "1.0.0"
|
||||
gunicorn = "^21.2.0"
|
||||
pyyaml = "^6.0"
|
||||
colorthief = "^0.2.1"
|
||||
Pillow = "^9.4.0"
|
||||
|
@ -28,6 +28,7 @@ cssmin = "^0.2.0"
|
|||
pylint = "^2.16.3"
|
||||
black = "^23.3.0"
|
||||
cachetools = "^5.3.0"
|
||||
material-color-utilities-python = "^0.1.5"
|
||||
|
||||
[build-system]
|
||||
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