diff --git a/gallery/__init__.py b/gallery/__init__.py index 90b2460..47ac985 100644 --- a/gallery/__init__.py +++ b/gallery/__init__.py @@ -5,7 +5,7 @@ print(""" | |_| | | | | | |_| | |__| __/ (_| \\__ \\ \\___/|_| |_|_|\\__, |_____\\___|\\__, |___/ |___/ |___/ -Created by Fluffy Bean - Version 250123 +Created by Fluffy Bean - Version 260123 """) from flask import Flask, render_template diff --git a/gallery/gallery.py b/gallery/gallery.py index a9bd750..5981971 100644 --- a/gallery/gallery.py +++ b/gallery/gallery.py @@ -1,10 +1,13 @@ from flask import Blueprint, flash, g, redirect, render_template, request, url_for, jsonify, current_app from werkzeug.exceptions import abort from werkzeug.utils import secure_filename + from gallery.auth import login_required from gallery.db import get_db + from PIL import Image from PIL.ExifTags import TAGS + import os import datetime @@ -26,20 +29,18 @@ def index(): def image(id): # Get image from database db = get_db() - image = db.execute('SELECT * FROM posts' - ' WHERE id = ?', (id, )).fetchone() + image = db.execute('SELECT * FROM posts WHERE id = ?', (id, )).fetchone() if image is None: abort(404) # Get exif data from image - try: - file = Image.open( - os.path.join(current_app.config['UPLOAD_FOLDER'], - image['file_name'])) - raw_exif = file.getexif() - human_exif = {} + file = Image.open( + os.path.join(current_app.config['UPLOAD_FOLDER'], image['file_name'])) + raw_exif = file.getexif() + human_exif = {} + try: for tag in raw_exif: name = TAGS.get(tag, tag) value = raw_exif.get(tag) @@ -48,19 +49,25 @@ def image(id): value = value.decode() human_exif[name] = value - - if len(human_exif) == 0: - human_exif = False - except: - # Cringe, no file present + except Exception as e: human_exif = False - file = False + + def human_size(num, suffix="B"): + for unit in ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"]: + if abs(num) < 1024.0: + return f"{num:3.1f}{unit}{suffix}" + num /= 1024.0 + return f"{num:.1f}Yi{suffix}" + + size = os.path.getsize( + os.path.join(current_app.config['UPLOAD_FOLDER'], image['file_name'])) # All in le head return render_template('image.html', image=image, exif=human_exif, - file=file) + file=file, + size=human_size(size)) @blueprint.route('/group') diff --git a/gallery/static/jquery-3.6.3.min.js b/gallery/static/js/jquery-3.6.3.min.js similarity index 100% rename from gallery/static/jquery-3.6.3.min.js rename to gallery/static/js/jquery-3.6.3.min.js diff --git a/gallery/static/js/login.js b/gallery/static/js/login.js new file mode 100644 index 0000000..b4c71ee --- /dev/null +++ b/gallery/static/js/login.js @@ -0,0 +1,110 @@ +function showLogin() { + popUpShow( + 'idk what to put here, just login please', + 'Need an account? Register!', + '', + '
\ + \ + \ + \ +
' + ); +}; +function showRegister() { + popUpShow( + 'Who are you?', + 'Already have an account? Login!', + '', + '
\ + \ + \ + \ + \ + \ +
' + ); +}; + +function login(event) { + // AJAX takes control of subby form + event.preventDefault(); + + if ($("#username").val() === "" || $("#password").val() === "") { + addNotification("Please fill in all fields", 3); + } else { + // Make form + var formData = new FormData(); + formData.append("username", $("#username").val()); + formData.append("password", $("#password").val()); + + $.ajax({ + url: '/auth/login', + type: 'post', + data: formData, + contentType: false, + processData: false, + success: function (response) { + location.reload(); + }, + error: function (response) { + switch (response.status) { + case 500: + addNotification('Server exploded, F\'s in chat', 2); + break; + case 403: + addNotification('None but devils play past here... Wrong information', 2); + break; + default: + addNotification('Error logging in, blame someone', 2); + break; + } + } + }); + } +} +function register(obj) { + // AJAX takes control of subby form + event.preventDefault(); + + if ($("#username").val() === "" || $("#email").val() === "" || $("#password").val() === "" || $("#password-repeat").val() === "") { + addNotification("Please fill in all fields", 3); + } else { + // Make form + var formData = new FormData(); + formData.append("username", $("#username").val()); + formData.append("email", $("#email").val()); + formData.append("password", $("#password").val()); + formData.append("password-repeat", $("#password-repeat").val()); + + $.ajax({ + url: '/auth/register', + type: 'post', + data: formData, + contentType: false, + processData: false, + success: function (response) { + if (response === "gwa gwa") { + addNotification('Registered successfully! Now please login to continue', 1); + showLogin(); + } else { + for (var i = 0; i < response.length; i++) { + addNotification(response[i], 2); + } + } + }, + error: function (response) { + switch (response.status) { + case 500: + addNotification('Server exploded, F\'s in chat', 2); + break; + case 403: + addNotification('None but devils play past here...', 2); + break; + default: + addNotification('Error logging in, blame someone', 2); + break; + } + } + }); + } +} \ No newline at end of file diff --git a/gallery/static/js/main.js b/gallery/static/js/main.js new file mode 100644 index 0000000..4695556 --- /dev/null +++ b/gallery/static/js/main.js @@ -0,0 +1,136 @@ +let navToggle = true; + +document.onscroll = function() { + document.querySelector('.background-decoration').style.opacity = `${1 - window.scrollY / 621}`; + document.querySelector('.background-decoration').style.top = `-${window.scrollY / 5}px`; + + if (document.body.scrollTop > 300 || document.documentElement.scrollTop > 20) { + document.querySelector('.jumpUp').style.opacity = 1; + document.querySelector('.jumpUp').style.right = "0.75rem"; + } else { + document.querySelector('.jumpUp').style.opacity = 0; + document.querySelector('.jumpUp').style.right = "-3rem"; + } +} + +document.querySelector('.jumpUp').onclick = function() { + document.body.scrollTop = 0; + document.documentElement.scrollTop = 0; +} + +function imgFade(obj) { + $(obj).animate({opacity: 1}, 500); + //$(obj).parent().style.backgroundColor = 'transparent'; +} + +function addNotification(text='Sample notification', type=4) { + var container = document.querySelector('.notifications'); + + // Create notification element + var div = document.createElement('div'); + div.classList.add('sniffle__notification'); + div.onclick = function() { + if (div.parentNode) { + div.classList.add('sniffle__notification--hide'); + + setTimeout(function() { + container.removeChild(div); + }, 500); + } + }; + + // Create icon element and append to notification + var icon = document.createElement('span'); + icon.classList.add('sniffle__notification-icon'); + switch (type) { + case 1: + div.classList.add('sniffle__notification--success'); + icon.innerHTML = '\ + \ + '; + break; + case 2: + div.classList.add('sniffle__notification--error'); + icon.innerHTML = '\ + \ + '; + break; + case 3: + div.classList.add('sniffle__notification--warning'); + icon.innerHTML = '\ + \ + '; + break; + default: + div.classList.add('sniffle__notification--info'); + icon.innerHTML = '\ + \ + '; + break; + } + div.appendChild(icon); + + // Create text element and append to notification + var description = document.createElement('span'); + description.classList.add('sniffle__notification-text'); + description.innerHTML = text; + div.appendChild(description); + + // Create span to show time remaining + var timer = document.createElement('span'); + timer.classList.add('sniffle__notification-time'); + div.appendChild(timer); + + // Append notification to container + container.appendChild(div); + setTimeout(function() { + div.classList.add('sniffle__notification-show'); + }, 100); + + // Remove notification after 5 seconds + setTimeout(function() { + if (div.parentNode) { + div.classList.add('sniffle__notification--hide'); + + setTimeout(function() { + container.removeChild(div); + }, 500); + } + }, 5000); +} + +function popUpShow(title, body, actions, content) { + var popup = document.querySelector('.pop-up'); + var popupContent = document.querySelector('.pop-up-content'); + var popupActions = document.querySelector('.pop-up-controlls'); + + // Set tile and description + h3 = document.createElement('h3'); + h3.innerHTML = title; + p = document.createElement('p'); + p.innerHTML = body; + + popupContent.innerHTML = ''; + popupContent.appendChild(h3); + popupContent.appendChild(p); + + // Set content + if (content != '') { + popupContent.innerHTML += content; + } + + // Set buttons that will be displayed + popupActions.innerHTML = ''; + if (actions != '') { + popupActions.innerHTML += actions; + } + popupActions.innerHTML += ''; + + // Show popup + popup.classList.add('pop-up__active'); +} + +function popupDissmiss() { + var popup = document.querySelector('.pop-up'); + popup.classList.remove('pop-up__active'); +} \ No newline at end of file diff --git a/gallery/static/js/upload.js b/gallery/static/js/upload.js new file mode 100644 index 0000000..67217f9 --- /dev/null +++ b/gallery/static/js/upload.js @@ -0,0 +1,70 @@ +function showUpload() { + popUpShow( + 'Upload funny stuff', + 'May the world see your stuff 👀', + '', + '
\ + \ + \ + \ + \ + \ +
' + ); +}; +function uploadFile(){ + // AJAX takes control of subby form + event.preventDefault(); + + // Check for empty upload + if ($("#file").val() === "") { + addNotification("Please select a file to upload", 2); + } else { + // Make form + var formData = new FormData(); + formData.append("file", $("#file").prop("files")[0]); + formData.append("alt", $("#alt").val()); + formData.append("description", $("#description").val()); + formData.append("tags", $("#tags").val()); + formData.append("submit", $("#submit").val()); + + // Upload the information + $.ajax({ + url: '/api/upload', + type: 'post', + data: formData, + contentType: false, + processData: false, + success: function (response) { + addNotification("File uploaded successfully!", 1); + // popupDissmiss(); // Close popup + }, + error: function (response) { + switch (response.status) { + case 500: + addNotification('Server exploded, F\'s in chat', 2); + break; + case 400: + case 404: + addNotification('Error uploading. Blame yourself', 2); + break; + case 403: + addNotification('None but devils play past here...', 2); + break; + case 413: + addNotification('File too large!!!!!!', 3); + break; + default: + addNotification('Error uploading file, blame someone', 2); + break; + } + } + }); + + // Empty values + $("#file").val(""); + $("#alt").val(""); + $("#description").val(""); + $("#tags").val(""); + } +}; \ No newline at end of file diff --git a/gallery/templates/image.html b/gallery/templates/image.html index 1118de7..c6ebfcd 100644 --- a/gallery/templates/image.html +++ b/gallery/templates/image.html @@ -6,16 +6,12 @@ {% endblock %} - +{% block scrollPosition %}?src={{ image['id'] }}{% endblock %} {% block wrapper_class %}image-wrapper{% endblock %} {% block content %}
- +
@@ -116,12 +112,11 @@

Image ID: {{ image['id'] }}

Author: {{ image['author_id'] }}

Upload date: {{ image['created_at'] }}

- {% if file is not false %} -

Dimensions: {{ file['width'] }}x{{ file['height'] }}

- {% endif %} +

Dimensions: {{ file['width'] }}x{{ file['height'] }}

+

File size: {{ size }}

- {% if exif is not false %} + {% if exif %}
@@ -147,6 +142,7 @@ $('#img-fullscreen').click(function() { $('.image-fullscreen').addClass('image-fullscreen__active'); + if ($('.image-fullscreen img').attr('src') == '') { $('.image-fullscreen img').attr('src', '/api/uploads/{{ image['file_name'] }}/0'); } diff --git a/gallery/templates/index.html b/gallery/templates/index.html index ee307f1..97da671 100644 --- a/gallery/templates/index.html +++ b/gallery/templates/index.html @@ -6,12 +6,11 @@ {% block content %}