Fix sql syntax

Add database initialisation
Reorganise default theme
This commit is contained in:
Michał Gdula 2023-01-08 15:14:35 +00:00
parent 122b1760cf
commit d85ac5f103
14 changed files with 409 additions and 302 deletions

19
app.py
View file

@ -1,8 +1,3 @@
# Import base packages
import time
import sys
import os
print("""
___ _ _
/ _ \ _ __ | |_ _| | ___ __ _ ___
@ -10,13 +5,19 @@ print("""
| |_| | | | | | |_| | |__| __/ (_| \__ \\
\___/|_| |_|_|\__, |_____\___|\__, |___/
|___/ |___/
Created by Fluffy Bean - Version: 060123
Created by Fluffy Bean - Version: 080123
""")
time.sleep(1)
# Import base packages
import time
import sys
import os
# Import required OnlyLegs packages
from packages import onlylegsDB
onlylegsDB = onlylegsDB.DBmanager()
onlylegsDB.initialize()
from packages import onlylegsSass
onlylegsSass = onlylegsSass.Sassy('default')
@ -94,8 +95,8 @@ def image_list(item_type):
if request.method != 'GET':
abort(405)
cursor = onlylegsDB.cursor()
cursor.execute("SELECT id,imagename FROM images ORDER BY id DESC")
cursor = onlylegsDB.database.cursor()
cursor.execute("SELECT * FROM posts ORDER BY id DESC")
item_list = cursor.fetchall()

View file

@ -1,4 +1,5 @@
import time
import datetime
now = datetime.datetime.now()
import sys
import os
@ -22,7 +23,7 @@ class DBmanager():
load_dotenv(env_path)
print("### OnlyLegs Database Manager ###")
print("Connecting to database...")
print(f"{now.hour}:{now.minute}:{now.second} - Connecting to database...")
database = mysql.connector.connect(host=os.environ.get('DB_HOST'),
port=os.environ.get('DB_PORT'),
@ -41,7 +42,7 @@ class DBmanager():
record = cursor.fetchone()
print("Connected to database:", record[0])
print("Done!\n")
print(f"{now.hour}:{now.minute}:{now.second} - Done!\n")
except Error as e:
print("Error while connecting to Database!\nFull error:", e)
@ -50,14 +51,54 @@ class DBmanager():
self.database = database
def cursor(self):
return self.database.cursor()
def initialize(self):
dir = os.path.join('packages', 'tables')
if not os.path.exists(dir+'/generate.sql'):
print("Error: could not find tables directory")
print("Exiting...")
sys.exit(1)
else:
print(f"{now.hour}:{now.minute}:{now.second} - Initializing tables...")
with open(dir+'/generate.sql', 'r') as f:
sql = f.read()
cursor = self.database.cursor()
query = cursor.execute(sql, multi=True)
for res in query:
#print("Running query...")
print(f"Affected {res.rowcount} rows")
self.database.commit()
if not os.path.exists(dir+'/junctions.sql'):
print("Error: could not find junctions directory")
print("Exiting...")
sys.exit(1)
else:
print(f"{now.hour}:{now.minute}:{now.second} - Initializing junctions...")
with open(dir+'/junctions.sql', 'r') as f:
sql = f.read()
cursor = self.database.cursor()
query = cursor.execute(sql, multi=True)
for res in query:
#print("Running query...")
print(f"Affected {res.rowcount} rows")
self.database.commit()
print(f"{now.hour}:{now.minute}:{now.second} - Done!\n")
def getImage(self, id):
sql = "SELECT * FROM images WHERE id = %s"
sql = "SELECT * FROM posts WHERE id = %s"
img = (id,)
cursor = self.cursor()
cursor = self.database.cursor()
cursor.execute(sql, img)
return cursor.fetchone()

View file

@ -1,4 +1,5 @@
import time
import datetime
now = datetime.datetime.now()
import sys
import shutil
import os
@ -6,6 +7,7 @@ import os
class Sassy():
def __init__(self, theme):
print("### OnlyLegs Theme Manager ###")
print(f"{now.hour}:{now.minute}:{now.second} - Loading theme...")
try:
import sass
@ -33,7 +35,7 @@ class Sassy():
else:
print("No fonts found!")
print("Done!\n")
print(f"{now.hour}:{now.minute}:{now.second} - Done!\n")
def loadTheme (self, theme):
with open('static/css/style.css', 'w') as f:

View file

@ -1,51 +1,67 @@
CREATE IF NOT EXISTS TABLE users (
id INT(69) PRIMARY KEY AUTO_INCREMENT,
CREATE TABLE IF NOT EXISTS users (
id INT(69) NOT NULL PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(255) NOT NULL UNIQUE,
email VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW() ON UPDATE NOW()
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
CREATE IF NOT EXISTS TABLE posts (
CREATE TABLE IF NOT EXISTS posts (
id INT(69) PRIMARY KEY AUTO_INCREMENT,
file_name VARCHAR(255) NOT NULL UNIQUE,
author_id INT(69) NOT NULL,
description TEXT NOT NULL,
alt TEXT NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW() ON UPDATE NOW()
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
CREATE IF NOT EXISTS TABLE groups (
CREATE TABLE IF NOT EXISTS groups (
id INT(69) PRIMARY KEY AUTO_INCREMENT,
author_id INT(69) NOT NULL,
name VARCHAR(255) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP NOT NULL DEFAULT NOW() ON UPDATE NOW()
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
CREATE IF NOT EXISTS TABLE permissions (
CREATE TABLE IF NOT EXISTS permissions (
id INT(69) PRIMARY KEY AUTO_INCREMENT,
user_id INT(69) NOT NULL,
admin BOOLEAN NOT NULL DEFAULT FALSE,
create_posts BOOLEAN NOT NULL DEFAULT TRUE,
updated_at TIMESTAMP NOT NULL DEFAULT NOW() ON UPDATE NOW()
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
CREATE IF NOT EXISTS TABLE logs (
CREATE TABLE IF NOT EXISTS devices (
id INT(69) PRIMARY KEY AUTO_INCREMENT,
user_id INT(69) NOT NULL,
device_id VARCHAR(255) NOT NULL,
cookie VARCHAR(255) NOT NULL,
ip VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS tokens (
id INT(69) PRIMARY KEY AUTO_INCREMENT,
token VARCHAR(255) NOT NULL UNIQUE,
is_used BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS logs (
id INT(69) PRIMARY KEY AUTO_INCREMENT,
ip VARCHAR(255) NOT NULL,
user_id INT(69) DEFAULT NULL,
code INT(69) NOT NULL,
note TEXT DEFAULT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW()
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE IF NOT EXISTS TABLE bans (
CREATE TABLE IF NOT EXISTS bans (
id INT(69) PRIMARY KEY AUTO_INCREMENT,
ip VARCHAR(255) NOT NULL,
code INT(69) NOT NULL,
note TEXT DEFAULT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW()
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

View file

@ -1,4 +1,4 @@
CREATE IF NOT EXISTS TABLE group_junction (
CREATE TABLE IF NOT EXISTS group_junction (
id INT(69) PRIMARY KEY AUTO_INCREMENT,
group_id INT(69) NOT NULL,
image_id INT(69) NOT NULL

View file

@ -29,7 +29,7 @@
<h2>${fileName}</h2>
</div>
<span class="gallery__item-filter"></span>
<img class="gallery__item-image" src="/uploads/original/${fileName}" onload="imgFade(this)" style="display:none;">
<img class="gallery__item-image" src="https://supersecreteuploadtest.leggy.dev/usr/images/${fileName}" onload="imgFade(this)" style="display:none;">
</a>
`;

View file

@ -10,18 +10,43 @@
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous">
</script>
<script src="https://unpkg.com/phosphor-icons" defer></script>
<!--<script src="https://unpkg.com/phosphor-icons" defer></script>-->
</head>
<body>
<nav id="navRoot">
<div>
<a href="{{ url_for('home') }}"><i class="ph-house-line"></i><span>Home</span></a>
<a href="{{ url_for('home') }}"><i class="ph-package"></i><span>Groups</span></a>
<a href="{{ url_for('home') }}"><i class="ph-upload"></i><span>Upload</span></a>
<a href="{{ url_for('home') }}">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-2 -2 24 24" width="24" fill="currentColor">
<path d="M18 18V7.132l-8-4.8-8 4.8V18h4v-2.75a4 4 0 1 1 8 0V18h4zm-6 2v-4.75a2 2 0 1 0-4 0V20H2a2 2 0 0 1-2-2V7.132a2 2 0 0 1 .971-1.715l8-4.8a2 2 0 0 1 2.058 0l8 4.8A2 2 0 0 1 20 7.132V18a2 2 0 0 1-2 2h-6z"></path>
</svg>
<span>Home</span>
</a>
<a href="{{ url_for('home') }}">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-2 -2 24 24" width="24" fill="currentColor">
<path d="M2 8v10h12V8H2zm2-2V2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-2v4a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h2zm2 0h8a2 2 0 0 1 2 2v4h2V2H6v4zm0 9a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0-2a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"></path><path d="M7 6a3 3 0 1 1 6 0h-2a1 1 0 0 0-2 0H7zm1.864 13.518l2.725-4.672a1 1 0 0 1 1.6-.174l1.087 1.184 1.473-1.354-1.088-1.183a3 3 0 0 0-4.8.52L7.136 18.51l1.728 1.007zm6.512-12.969a2.994 2.994 0 0 1 3.285.77l1.088 1.183-1.473 1.354-1.087-1.184A1 1 0 0 0 16 8.457V8c0-.571-.24-1.087-.624-1.451z"></path>
</svg>
<span>Groups</span>
</a>
<a href="{{ url_for('home') }}">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-5 -5 24 24" width="24" fill="currentColor">
<path d="M8 3.414v5.642a1 1 0 1 1-2 0V3.414L4.879 4.536A1 1 0 0 1 3.464 3.12L6.293.293a1 1 0 0 1 1.414 0l2.829 2.828A1 1 0 1 1 9.12 4.536L8 3.414zM1 12h12a1 1 0 0 1 0 2H1a1 1 0 0 1 0-2z"></path>
</svg>
<span>Upload</span>
</a>
</div>
<div>
<a href="{{ url_for('home') }}"><i class="ph-user-circle"></i><span>Profile</span></a>
<a href="{{ url_for('home') }}"><i class="ph-gear"></i><span>Settings</span></a>
<a href="{{ url_for('home') }}">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-2 -2 24 24" width="24" fill="currentColor">
<path d="M10 20C4.477 20 0 15.523 0 10S4.477 0 10 0s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm0-14a4 4 0 0 1 4 4v2a4 4 0 1 1-8 0V8a4 4 0 0 1 4-4zm0 2a2 2 0 0 0-2 2v2a2 2 0 1 0 4 0V8a2 2 0 0 0-2-2zM5.91 16.876a8.033 8.033 0 0 1-1.58-1.232 5.57 5.57 0 0 1 2.204-1.574 1 1 0 1 1 .733 1.86c-.532.21-.993.538-1.358.946zm8.144.022a3.652 3.652 0 0 0-1.41-.964 1 1 0 1 1 .712-1.868 5.65 5.65 0 0 1 2.284 1.607 8.032 8.032 0 0 1-1.586 1.225z"></path>
</svg>
<span>Profile</span>
</a>
<a href="{{ url_for('home') }}">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-5 -7 24 24" width="24" fill="currentColor">
<path d="M1 0h5a1 1 0 1 1 0 2H1a1 1 0 1 1 0-2zm7 8h5a1 1 0 0 1 0 2H8a1 1 0 1 1 0-2zM1 4h12a1 1 0 0 1 0 2H1a1 1 0 1 1 0-2z"></path>
</svg>
<span>Settings</span>
</a>
</div>
</nav>
<main>

View file

@ -0,0 +1,29 @@
#topButton {
margin: 0;
padding: 0.25rem;
position: fixed;
bottom: 0.75rem;
right: -3rem;
font-size: 3rem;
display: flex; // hidden
justify-content: center;
align-items: center;
border-radius: 50%;
background-color: $black300;
opacity: 0; // hidden
z-index: 2;
cursor: pointer;
transition: all 0.2s cubic-bezier(.86, 0, .07, 1);
&:hover {
background-color: $black200;
color: $green;
}
}

View file

@ -1,241 +1,12 @@
$black100: #151515;
$black200: #121212;
$black300: #101010;
$black400: #0e0e0e;
@import 'variables/variables';
@import 'variables/fonts';
$white100: #e8e3e3;
$red: #B66467;
$orange: #D8A657;
$yellow: #D9BC8C;
$green: #8C977D;
$blue: #8DA3B9;
$purple: #A988B0;
$rad: 8px;
$font-header: "Hubot-Sans", sans-serif;
$font-body: "Mona-Sans", sans-serif;
@font-face {
font-family: "Mona-Sans";
src: url("../fonts/Mona-Sans.woff2") format("woff2 supports variations"),
url("../fonts/Mona-Sans.woff2") format("woff2-variations");
font-weight: 200 900;
font-stretch: 75% 125%;
font-display: swap;
}
@font-face {
font-family: "Hubot-Sans";
src: url("../fonts/Hubot-Sans.woff2") format("woff2 supports variations"),
url("../fonts/Hubot-Sans.woff2") format("woff2-variations");
font-weight: 200 900;
font-stretch: 75% 125%;
font-display: swap;
}
@font-face {
font-family: 'Work Sans';
src: url('fonts/worksans-regular.woff2');
font-weight: 400;
}
@font-face {
font-family: 'Work Sans';
src: url('fonts/worksans-bold.woff2');
font-weight: 600;
}
@font-face {
font-family: 'Work Sans';
src: url('fonts/worksans-black.woff2');
font-weight: 900;
}
@import 'ui/reset';
@import 'ui/nav';
@import 'ui/main';
@import 'buttons/btn';
html, body {
margin: 0;
padding: 0;
min-height: 100vh;
background-color: $black100;
scroll-behavior: smooth;
}
nav {
margin: 0;
padding: 0;
max-width: calc(100vw - 3.5rem);
width: 3.5rem;
height: 100dvh;
display: flex;
flex-direction: column;
justify-content: space-between;
position: fixed;
top: 0;
left: 0;
background-color: $black300;
color: $white100;
box-sizing: border-box;
z-index: 2;
overflow: hidden;
transition: width 0.4s cubic-bezier(.86,0,.07,1), background-color 0.3s ease-in-out;
&:hover {
width: 30rem;
a span {
opacity: 1;
}
}
div {
display: flex;
flex-direction: column;
gap: 0.25rem;
a {
margin: 0;
padding: 1rem 1rem 1rem calc(1rem - 2px);
width: 100%;
height: 3.5rem;
display: flex;
flex-direction: row;
align-items: center;
gap: 0.5rem;
text-decoration: none;
color: $white100;
border-left: 2px solid #00000000;
box-sizing: border-box;
i {
margin: 0;
font-size: 1.5rem;
color: $white100;
}
span {
display: block;
font-family: $font-body;
font-size: 1.25rem;
font-stretch: expanded;
font-weight: 500;
color: $white100;
opacity: 0; // hidden
transition: opacity 0.3s ease-in-out;
}
&:hover {
background-color: $black200;
border-left: 2px solid $green;
* {
color: $green;
}
}
}
}
}
main {
margin: 0;
padding: 0;
background-color: $black100;
color: $white100;
min-height: 100vh;
overflow-y: auto;
box-sizing: border-box;
header {
margin: 0;
padding: 0;
width: 100%;
height: 40vh;
position: relative;
background-color: $black200;
border-radius: $rad;
box-sizing: border-box;
img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
filter: blur(0.5rem);
object-fit: cover;
object-position: center 0px;
}
span {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: linear-gradient(to bottom, #00000000, rgba($black100, 1));
z-index: +1;
}
}
}
#topButton {
margin: 0;
padding: 0.25rem;
position: fixed;
bottom: 0.75rem;
right: -3rem;
font-size: 3rem;
display: flex; // hidden
justify-content: center;
align-items: center;
border-radius: 50%;
background-color: $black300;
opacity: 0; // hidden
z-index: 2;
cursor: pointer;
transition: all 0.2s cubic-bezier(.86,0,.07,1);
&:hover {
background-color: $black200;
color: $green;
}
}
@import 'buttons/up';
.app {
margin: 0 0 0 3.5rem;
@ -274,9 +45,11 @@ main {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
@ -300,9 +73,9 @@ main {
position: relative;
background: linear-gradient(-45deg, $black100, $black400, $black100);
background: linear-gradient(-45deg, $black100, $black400 40%, $black100);
background-size: 400% 400%;
border-radius: calc($rad / 2);
border-radius: $rad;
animation: imgLoading 10s ease infinite;
box-sizing: border-box;
@ -376,7 +149,8 @@ main {
opacity: 1;
transform: scale(1);
h2, p {
h2,
p {
opacity: 1;
}
}
@ -398,7 +172,7 @@ main {
object-fit: cover;
object-position: center;
border-radius: calc($rad / 2);
border-radius: $rad;
}
}
@ -417,7 +191,7 @@ main {
display: flex;
overflow: hidden;
border-radius: calc($rad / 2);
border-radius: $rad;
box-sizing: border-box;
@ -431,9 +205,10 @@ main {
object-fit: contain;
object-position: center;
border-radius: calc($rad / 2);
border-radius: $rad;
}
}
.image__info {
margin: 0;
padding: 0;
@ -462,6 +237,7 @@ main {
text-overflow: ellipsis;
overflow: hidden;
}
p {
margin: 0;
padding: 0 1rem 0.5rem;

View file

@ -0,0 +1,54 @@
main {
margin: 0;
padding: 0;
background-color: $black100;
color: $white100;
min-height: 100vh;
overflow-y: auto;
box-sizing: border-box;
header {
margin: 0;
padding: 0;
width: 100%;
height: 40vh;
position: relative;
background-color: $black200;
border-radius: $rad;
box-sizing: border-box;
img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
filter: blur(0.5rem);
object-fit: cover;
object-position: center 0px;
}
span {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-image: linear-gradient(to bottom, #00000000, rgba($black100, 1));
z-index: +1;
}
}
}

View file

@ -0,0 +1,95 @@
nav {
margin: 0;
padding: 0;
max-width: 100vw;
width: 3.5rem;
height: 100dvh;
display: flex;
flex-direction: column;
justify-content: space-between;
position: fixed;
top: 0;
left: 0;
background-color: $black300;
color: $white100;
box-sizing: border-box;
z-index: 2;
transition: width 0.4s cubic-bezier(.76,0,.17,1), background-color 0.3s ease-in-out;
div {
display: flex;
flex-direction: column;
//gap: 0.25rem;
a {
margin: 0;
padding: 1rem;
width: 3.5rem;
height: 3.5rem;
display: flex;
flex-direction: row;
align-items: center;
//gap: 0.5rem;
position: relative;
text-decoration: none;
color: $white100;
box-sizing: border-box;
i, svg {
margin: 0;
font-size: 1.5rem;
color: $white100;
transition: color 0.2s ease-out;
}
span {
margin: 0;
padding: 0.5rem 1rem;
display: block;
position: absolute;
top: 50%;
left: 3rem;
transform: translateY(-50%);
font-family: $font-body;
font-size: 1rem;
font-weight: 600;
background-color: $black300;
color: $white100;
opacity: 0;
border-radius: $rad;
transition: opacity 0.2s cubic-bezier(.76,0,.17,1), left 0.2s cubic-bezier(.76,0,.17,1);
pointer-events: none;
}
&:hover {
//background-color: $black200;
i, svg {
color: $green;
}
span {
opacity: 1;
left: 3.8rem;
//transition-delay: 0.5s;
}
}
}
}
}

View file

@ -0,0 +1,15 @@
* {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
min-height: 100vh;
background-color: $black100;
scroll-behavior: smooth;
}

View file

@ -0,0 +1,35 @@
@font-face {
font-family: "Mona-Sans";
src: url("fonts/Mona-Sans.woff2") format("woff2 supports variations"),
url("fonts/Mona-Sans.woff2") format("woff2-variations");
font-weight: 200 900;
font-stretch: 75% 125%;
font-display: swap;
}
@font-face {
font-family: "Hubot-Sans";
src: url("fonts/Hubot-Sans.woff2") format("woff2 supports variations"),
url("fonts/Hubot-Sans.woff2") format("woff2-variations");
font-weight: 200 900;
font-stretch: 75% 125%;
font-display: swap;
}
@font-face {
font-family: 'Work Sans';
src: url('fonts/worksans-regular.woff2');
font-weight: 400;
}
@font-face {
font-family: 'Work Sans';
src: url('fonts/worksans-bold.woff2');
font-weight: 600;
}
@font-face {
font-family: 'Work Sans';
src: url('fonts/worksans-black.woff2');
font-weight: 900;
}

View file

@ -0,0 +1,18 @@
$black100: #151515;
$black200: #121212;
$black300: #101010;
$black400: #0e0e0e;
$white100: #e8e3e3;
$red: #B66467;
$orange: #D8A657;
$yellow: #D9BC8C;
$green: #8C977D;
$blue: #8DA3B9;
$purple: #A988B0;
$rad: 8px;
$font-header: "Work Sans", sans-serif;
$font-body: "Work Sans", sans-serif;