From d0d5c4b95fb091a739c1f1d3b7e493faffb95316 Mon Sep 17 00:00:00 2001 From: Logan Endes Date: Thu, 12 Feb 2026 16:23:48 -0500 Subject: [PATCH 1/7] feat: support for m4a and mov, with some heic files supported, and nef in progress --- Dockerfile | 2 +- gallery/file_modules/__init__.py | 11 +++++++++- gallery/file_modules/heic.py | 35 ++++++++++++++++++++++++++++++++ gallery/file_modules/m4a.py | 18 ++++++++++++++++ gallery/file_modules/mov.py | 33 ++++++++++++++++++++++++++++++ gallery/file_modules/nef.py | 26 ++++++++++++++++++++++++ 6 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 gallery/file_modules/heic.py create mode 100644 gallery/file_modules/m4a.py create mode 100644 gallery/file_modules/mov.py create mode 100644 gallery/file_modules/nef.py diff --git a/Dockerfile b/Dockerfile index 219a7be..adbebee 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ MAINTAINER Computer Science House ENV IMAGEIO_USERDIR /var/lib/gallery RUN apt-get update && \ - apt-get install -y libldap-dev libsasl2-dev libmagic-dev ghostscript libldap-common && \ + apt-get install -y libldap-dev libsasl2-dev libmagic-dev ghostscript libldap-common imagemagick libheif1 libheif-dev libraw-dev libraw20 dcraw && \ apt-get autoremove --yes && \ apt-get clean autoclean && \ sed -i \ diff --git a/gallery/file_modules/__init__.py b/gallery/file_modules/__init__.py index b2a8030..235b541 100644 --- a/gallery/file_modules/__init__.py +++ b/gallery/file_modules/__init__.py @@ -65,6 +65,10 @@ def generate_thumbnail(self): from gallery.file_modules.txt import TXTFile from gallery.file_modules.mp3 import MP3File from gallery.file_modules.wav import WAVFile +from gallery.file_modules.heic import HEICFile +from gallery.file_modules.nef import NEFFile +from gallery.file_modules.mov import MOVFile +from gallery.file_modules.m4a import M4AFile file_mimetype_relation = { "image/jpeg": JPEGFile, @@ -76,13 +80,18 @@ def generate_thumbnail(self): "image/x-windows-bmp": BMPFile, "image/tiff": TIFFFile, "image/x-tiff": TIFFFile, + "image/heic": HEICFile, + "image/x-nikon-nef": NEFFile, "video/mp4": MP4File, "video/webm": WebMFile, "video/ogg": OggFile, + "video/quicktime": MOVFile, "application/pdf": PDFFile, "text/plain": TXTFile, "audio/mpeg": MP3File, - "audio/x-wav": WAVFile + "audio/x-wav": WAVFile, + "audio/mp4": M4AFile, + "audio/x-m4a": M4AFile, } diff --git a/gallery/file_modules/heic.py b/gallery/file_modules/heic.py new file mode 100644 index 0000000..a38d876 --- /dev/null +++ b/gallery/file_modules/heic.py @@ -0,0 +1,35 @@ +import os +from wand.image import Image +from wand.color import Color + +from gallery.file_modules import FileModule +from gallery.util import hash_file + + +class HEICFile(FileModule): + def __init__(self, file_path, dir_path): + FileModule.__init__(self, file_path, dir_path) + self.mime_type = "image/heic" + + self.generate_thumbnail() + + def generate_thumbnail(self): + self.thumbnail_uuid = hash_file(self.file_path) + ".jpg" + + with Image(filename=self.file_path) as img: + with Image(width=img.width, height=img.height, background=Color("#EEEEEE")) as bg: + # Fix orientation from EXIF + img.auto_orient() + # Force proper colorspace conversion + img.transform_colorspace('srgb') + # Remove alpha if present + img.alpha_channel = 'remove' + # Strip ICC/HDR metadata (prevents weird color shifts) + img.strip() + # Same process as other image types + bg.composite(img, 0, 0) + size = img.width if img.width < img.height else img.height + bg.crop(width=size, height=size, gravity='center') + bg.resize(256, 256) + bg.format = 'jpeg' + bg.save(filename=os.path.join(self.dir_path, self.thumbnail_uuid)) \ No newline at end of file diff --git a/gallery/file_modules/m4a.py b/gallery/file_modules/m4a.py new file mode 100644 index 0000000..155f3ff --- /dev/null +++ b/gallery/file_modules/m4a.py @@ -0,0 +1,18 @@ +import os +from wand.image import Image + +from gallery.file_modules import FileModule +from gallery.util import hash_file + +class M4AFile(FileModule): + def __init__(self, file_path, dir_path): + FileModule.__init__(self, file_path, dir_path) + self.mime_type = "audio/mp4" + + self.generate_thumbnail() + + def generate_thumbnail(self): + self.thumbnail_uuid = hash_file(self.file_path) + ".jpg" + + with Image(filename="thumbnails/reedphoto.jpg") as bg: + bg.save(filename=os.path.join(self.dir_path, self.thumbnail_uuid)) diff --git a/gallery/file_modules/mov.py b/gallery/file_modules/mov.py new file mode 100644 index 0000000..a99be5d --- /dev/null +++ b/gallery/file_modules/mov.py @@ -0,0 +1,33 @@ +from moviepy.editor import VideoFileClip +import os +from wand.image import Image +from wand.color import Color + +from gallery.file_modules import FileModule +from gallery.util import hash_file + + +class MOVFile(FileModule): + + def __init__(self, file_path, dir_path): + FileModule.__init__(self, file_path, dir_path) + self.mime_type = "video/quicktime" + + self.generate_thumbnail() + + def generate_thumbnail(self): + self.thumbnail_uuid = hash_file(self.file_path) + ".jpg" + thumbnail_loc = os.path.join(self.dir_path, self.thumbnail_uuid) + + clip = VideoFileClip(self.file_path) + time_mark = clip.duration * 0.05 + clip.save_frame(thumbnail_loc, t=time_mark) + + with Image(filename=thumbnail_loc) as img: + with img.clone() as image: + size = image.width if image.width < image.height else image.height + image.crop(width=size, height=size, gravity='center') + image.resize(256, 256) + image.background_color = Color("#EEEEEE") + image.format = 'jpeg' + image.save(filename=thumbnail_loc) diff --git a/gallery/file_modules/nef.py b/gallery/file_modules/nef.py new file mode 100644 index 0000000..6d89382 --- /dev/null +++ b/gallery/file_modules/nef.py @@ -0,0 +1,26 @@ +import os +from wand.image import Image +from wand.color import Color + +from gallery.file_modules import FileModule +from gallery.util import hash_file + + +class NEFFile(FileModule): + def __init__(self, file_path, dir_path): + FileModule.__init__(self, file_path, dir_path) + self.mime_type = "image/x-nikon-nef" + + self.generate_thumbnail() + + def generate_thumbnail(self): + self.thumbnail_uuid = hash_file(self.file_path) + ".jpg" + + with Image(filename=self.file_path) as img: + with Image(width=img.width, height=img.height, background=Color("#EEEEEE")) as bg: + bg.composite(img, 0, 0) + size = img.width if img.width < img.height else img.height + bg.crop(width=size, height=size, gravity='center') + bg.resize(256, 256) + bg.format = 'jpeg' + bg.save(filename=os.path.join(self.dir_path, self.thumbnail_uuid)) \ No newline at end of file From abbb921e36ef4ffdb2bc98f42d6180620adf537d Mon Sep 17 00:00:00 2001 From: Logan Endes Date: Thu, 12 Feb 2026 16:46:36 -0500 Subject: [PATCH 2/7] NEF and HEIC files upload correctly --- gallery/file_modules/__init__.py | 6 ++++++ gallery/file_modules/heic.py | 33 ++++++++++++++------------------ gallery/file_modules/nef.py | 23 ++++++++++++---------- requirements.txt | 5 +++++ 4 files changed, 38 insertions(+), 29 deletions(-) diff --git a/gallery/file_modules/__init__.py b/gallery/file_modules/__init__.py index 235b541..60e6bd7 100644 --- a/gallery/file_modules/__init__.py +++ b/gallery/file_modules/__init__.py @@ -98,6 +98,12 @@ def generate_thumbnail(self): # classism def parse_file_info(file_path: str, dir_path: str) -> Tuple[str, Optional[FileModule]]: print("entering parse_file_info") + ext = os.path.splitext(file_path)[-1].lower() + # .nef is a RAW file + if ext == ".nef": # .nef is a special case, magic reads it as .tiff, but it is not processed correctly by the tiff module + print("image/x-nikon-nef") + print(file_path) + return "image/x-nikon-nef", NEFFile(file_path, dir_path) mime_type = magic.from_file(file_path, mime=True) print(mime_type) print(file_path) diff --git a/gallery/file_modules/heic.py b/gallery/file_modules/heic.py index a38d876..93c2034 100644 --- a/gallery/file_modules/heic.py +++ b/gallery/file_modules/heic.py @@ -1,10 +1,11 @@ import os -from wand.image import Image -from wand.color import Color +from PIL import Image as PILImage +import pillow_heif from gallery.file_modules import FileModule from gallery.util import hash_file +pillow_heif.register_heif_opener() class HEICFile(FileModule): def __init__(self, file_path, dir_path): @@ -16,20 +17,14 @@ def __init__(self, file_path, dir_path): def generate_thumbnail(self): self.thumbnail_uuid = hash_file(self.file_path) + ".jpg" - with Image(filename=self.file_path) as img: - with Image(width=img.width, height=img.height, background=Color("#EEEEEE")) as bg: - # Fix orientation from EXIF - img.auto_orient() - # Force proper colorspace conversion - img.transform_colorspace('srgb') - # Remove alpha if present - img.alpha_channel = 'remove' - # Strip ICC/HDR metadata (prevents weird color shifts) - img.strip() - # Same process as other image types - bg.composite(img, 0, 0) - size = img.width if img.width < img.height else img.height - bg.crop(width=size, height=size, gravity='center') - bg.resize(256, 256) - bg.format = 'jpeg' - bg.save(filename=os.path.join(self.dir_path, self.thumbnail_uuid)) \ No newline at end of file + thumb_path = os.path.join(self.dir_path, self.thumbnail_uuid) + + img = PILImage.open(self.file_path).convert("RGB") + + size = min(img.width, img.height) + left = (img.width - size) // 2 + top = (img.height - size) // 2 + img = img.crop((left, top, left + size, top + size)) + + img = img.resize((256, 256)) + img.save(thumb_path, "JPEG") \ No newline at end of file diff --git a/gallery/file_modules/nef.py b/gallery/file_modules/nef.py index 6d89382..b880636 100644 --- a/gallery/file_modules/nef.py +++ b/gallery/file_modules/nef.py @@ -1,6 +1,6 @@ import os -from wand.image import Image -from wand.color import Color +import rawpy +import imageio from gallery.file_modules import FileModule from gallery.util import hash_file @@ -15,12 +15,15 @@ def __init__(self, file_path, dir_path): def generate_thumbnail(self): self.thumbnail_uuid = hash_file(self.file_path) + ".jpg" + thumb_path = os.path.join(self.dir_path, self.thumbnail_uuid) - with Image(filename=self.file_path) as img: - with Image(width=img.width, height=img.height, background=Color("#EEEEEE")) as bg: - bg.composite(img, 0, 0) - size = img.width if img.width < img.height else img.height - bg.crop(width=size, height=size, gravity='center') - bg.resize(256, 256) - bg.format = 'jpeg' - bg.save(filename=os.path.join(self.dir_path, self.thumbnail_uuid)) \ No newline at end of file + with rawpy.imread(self.file_path) as raw: + rgb = raw.postprocess(output_bps=8) + + h, w, _ = rgb.shape + size = min(h, w) + y = (h - size) // 2 + x = (w - size) // 2 + rgb = rgb[y:y+size, x:x+size] + + imageio.imwrite(thumb_path, rgb) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index a5b9de1..39d2aec 100644 --- a/requirements.txt +++ b/requirements.txt @@ -70,3 +70,8 @@ Werkzeug==3.1.3 wrapt==1.17.2 xmltodict==0.14.2 zipp==3.19.1 +# NEF and HEIC support +pillow +pillow-heif +rawpy +imageio \ No newline at end of file From 140d4cdac115b9fea2827c3db637f855db48cf44 Mon Sep 17 00:00:00 2001 From: Logan Endes Date: Fri, 13 Feb 2026 13:53:19 -0500 Subject: [PATCH 3/7] Differentiate NEF from TIFF by checking if the file is parsable by rawpy instead of by extensions --- gallery/file_modules/__init__.py | 18 ++++++++++++------ requirements.txt | 8 ++++---- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/gallery/file_modules/__init__.py b/gallery/file_modules/__init__.py index 60e6bd7..a54a6e9 100644 --- a/gallery/file_modules/__init__.py +++ b/gallery/file_modules/__init__.py @@ -3,6 +3,7 @@ from typing import Any, Dict, List, Optional, Tuple from wand.image import Image from wand.color import Color +import rawpy from gallery.util import DEFAULT_THUMBNAIL_NAME from gallery.util import hash_file @@ -98,13 +99,18 @@ def generate_thumbnail(self): # classism def parse_file_info(file_path: str, dir_path: str) -> Tuple[str, Optional[FileModule]]: print("entering parse_file_info") - ext = os.path.splitext(file_path)[-1].lower() - # .nef is a RAW file - if ext == ".nef": # .nef is a special case, magic reads it as .tiff, but it is not processed correctly by the tiff module - print("image/x-nikon-nef") - print(file_path) - return "image/x-nikon-nef", NEFFile(file_path, dir_path) + mime_type = magic.from_file(file_path, mime=True) + + if "tif" in mime_type: # .nef is a special case, magic reads it as .tiff, but it is not processed correctly by the tiff module + # check if it is a raw file + try: + with rawpy.imread(file_path): # this may cause issues for other raw files + mime_type = "image/x-nikon-nef" + except rawpy.LibRawFileUnsupportedError: + pass + except rawpy.LibRawIOError: + pass print(mime_type) print(file_path) diff --git a/requirements.txt b/requirements.txt index 39d2aec..ed75835 100644 --- a/requirements.txt +++ b/requirements.txt @@ -71,7 +71,7 @@ wrapt==1.17.2 xmltodict==0.14.2 zipp==3.19.1 # NEF and HEIC support -pillow -pillow-heif -rawpy -imageio \ No newline at end of file +pillow==11.1.0 +pillow_heif==1.2.0 +rawpy==0.26.1 +imageio==2.4.0 \ No newline at end of file From 4976cbdc13cb8e9e677f8398e5334d05796e5b18 Mon Sep 17 00:00:00 2001 From: Cole Stowell Date: Sat, 18 Apr 2026 14:39:21 -0400 Subject: [PATCH 4/7] fix: use thumbnail_uuid for the thumbnail instead of s3_id --- gallery/__init__.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gallery/__init__.py b/gallery/__init__.py index 36b55e4..b2b2825 100644 --- a/gallery/__init__.py +++ b/gallery/__init__.py @@ -866,7 +866,11 @@ def display_thumbnail(file_id: int, auth_dict: Optional[Dict[str, Any]] = None): file_model = File.query.filter(File.id == file_id).first() - link = storage_interface.get_link("thumbnails/{}".format(file_model.s3_id)) + thumbnail_uuid = file_model.thumbnail_uuid + if len(thumbnail_uuid.split('.')) > 1: + thumbnail_uuid = thumbnail_uuid.split('.')[0] + + link = storage_interface.get_link("thumbnails/{}".format(thumbnail_uuid)) if "LOCAL_STORAGE_PATH" in app.config: link = "http://" + app.config["SERVER_NAME"] + link req = requests.get(link) From 25f783c0a346d2b0bd2b3e21295128e613e4816f Mon Sep 17 00:00:00 2001 From: aln730 Date: Sat, 25 Apr 2026 20:47:58 -0400 Subject: [PATCH 5/7] chunk uploads --- gallery/__init__.py | 107 ++++++++++++++++++++++++++++++- gallery/templates/view_dir.html | 48 ++++++++++---- gallery/templates/view_file.html | 2 +- 3 files changed, 142 insertions(+), 15 deletions(-) diff --git a/gallery/__init__.py b/gallery/__init__.py index b2b2825..2049b2f 100644 --- a/gallery/__init__.py +++ b/gallery/__init__.py @@ -40,6 +40,7 @@ import flask_migrate import requests from werkzeug.utils import secure_filename +import shutil app = Flask(__name__) app.config.update({ @@ -56,7 +57,7 @@ if os.path.exists(os.path.join(os.getcwd(), "config.py")): app_config.from_pyfile(os.path.join(os.getcwd(), "config.py")) else: - app_config.from_pyfile(os.path.join(os.getcwd(), "config.env.py")) + app_config.from_pyfile(os.path.join(os.getcwd(), "localconfig.env.py")) app.config.update(app_config) db: SQLAlchemy = SQLAlchemy(app) @@ -1056,7 +1057,7 @@ def render_dir(dir_id: int, auth_dict: Optional[Dict[str, Any]] = None): dir_model = Directory.query.filter(Directory.id == dir_id).first() if dir_model is None: abort(404) - description = dir_model.description + description = dir_model.description or "" display_description = len(description) > 0 display_parent = True @@ -1104,7 +1105,7 @@ def render_file(file_id: int, auth_dict: Optional[Dict[str, Any]] = None): if gallery_lockdown and (not auth_dict['is_eboard'] and not auth_dict['is_rtp']): abort(405) - description = file_model.caption + description = file_model.caption or "" display_description = len(description) > 0 display_parent = True if file_model is None or file_model.parent is None: @@ -1139,6 +1140,106 @@ def render_file(file_id: int, auth_dict: Optional[Dict[str, Any]] = None): lockdown=gallery_lockdown) +@app.route('/upload/chunk', methods=['POST']) +@auth.oidc_auth('default') +@gallery_auth +def upload_chunk(auth_dict: Optional[Dict[str, Any]] = None): + chunk = request.files.get('gallery-upload') + if chunk is None: + return jsonify({'error': 'no chunk'}), 400 + + dz_uuid = request.form.get('dzuuid') + chunk_index = int(request.form.get('dzchunkindex', 0)) + chunk_size = int(request.form.get('dzchunksize', 0)) + filename = secure_filename(request.form.get('dzfilename', '')) + + if not dz_uuid or not filename: + return jsonify({'error': 'missing chunk metadata'}), 400 + + chunk_dir = os.path.join(tempfile.gettempdir(), 'chonks', dz_uuid) + os.makedirs(chunk_dir, exist_ok=True) + + out_path = os.path.join(chunk_dir, 'assembled') + with open(out_path, 'ab') as out: + out.write(chunk.read()) + + return jsonify({'status': 'ok', 'chunk': chunk_index}), 200 + + +@app.route('/upload/chunk/finalize', methods=['POST']) +@auth.oidc_auth('default') +@gallery_auth +def finalize_upload(auth_dict: Optional[Dict[str, Any]] = None): + assert auth_dict is not None + owner = auth_dict['uuid'] + parent = request.form.get('parent_id') + dz_uuid = request.form.get('dzuuid') + filename = secure_filename(request.form.get('filename', '')) + total_chunks = int(request.form.get('dztotalchunkcount', 0)) + + if not all([parent, dz_uuid, filename, total_chunks]): + return jsonify({'error': 'missing parameters'}), 400 + + chunk_dir = os.path.join(tempfile.gettempdir(), 'chonks', dz_uuid) + + upload_status: Dict[str, Any] = {} + upload_status['redirect'] = '/view/dir/' + str(parent) + errors: List[str] = [] + success: List[Dict[str, Any]] = [] + + file_model = File.query.filter(File.parent == parent) \ + .filter(File.name == filename).first() + if file_model is not None: + errors.append(filename) + upload_status['error'] = errors + upload_status['success'] = success + return jsonify(upload_status), 200 + + dir_path = tempfile.mkdtemp() + filepath = os.path.join(dir_path, filename) + try: + assembled_path = os.path.join(chunk_dir, 'assembled') + if not os.path.exists(assembled_path): + return jsonify({'error': 'assembled file missing'}), 400 + shutil.move(assembled_path, filepath) + try: + mime, file_model = add_file(filename, dir_path, parent, '', owner) + except OSError as e: + if e.errno == 28: + return jsonify({'error': 'storage full'}), 507 + raise + if file_model is None: + errors.append(filename) + else: + with open(filepath, 'rb') as f_hnd: + storage_interface.put( + 'files/{}'.format(file_model.s3_id), + f_hnd, + filename, + mime + ) + os.remove(filepath) + + thumb_path = os.path.join(dir_path, file_model.thumbnail_uuid) + with open(thumb_path, 'rb') as f_hnd: + storage_interface.put( + 'thumbnails/' + file_model.s3_id, + f_hnd, + 'thumb_' + filename + '.' + thumb_path.split('.')[-1], + 'image/gif' if thumb_path.endswith('.gif') else 'image/jpeg' + ) + os.remove(thumb_path) + success.append({'name': file_model.name, 'id': file_model.id}) + finally: + shutil.rmtree(chunk_dir, ignore_errors=True) + shutil.rmtree(dir_path, ignore_errors=True) + + upload_status['error'] = errors + upload_status['success'] = success + refresh_default_thumbnails() + return jsonify(upload_status), 200 + + @app.route("/view/random_file") @auth.oidc_auth('default') def get_random_file(): diff --git a/gallery/templates/view_dir.html b/gallery/templates/view_dir.html index 3bc1c66..127cf04 100644 --- a/gallery/templates/view_dir.html +++ b/gallery/templates/view_dir.html @@ -245,23 +245,23 @@ Dropzone.autoDiscover = false; $(function() { - + var myDropzone = new Dropzone('div#galleryUpload', { - url: '/upload', + url: '/upload/chunk', paramName: "gallery-upload", uploadMultiple: false, autoProcessQueue: false, parallelUploads: 3, - success: afterUpload, - maxFilesize: 1024, + maxFilesize: 10 * 1024, + chunking: true, + forceChunking: true, + chunkSize: 10 * 1024 * 1024, + retryChunks: true, + retryChunksLimit: 3, + timeout: 0, init: function() { this.on('addedfile', function(file) { console.log(file.name + ": " + file.size); - if (file.size > (1024 * 1024 * 1024)) { - var warning = "
File \"" + file.name + "\" is too large, max filesize is 1GB.
"; - $('#upload').after(warning); - this.removeFile(file); - } }); this.on('accept', function(file, done) { @@ -269,10 +269,36 @@ }); this.on('sending', function(file, xhr, formData) { - formData.append('parent_id', "{{directory.id}}"); + formData.append('parent_id', '{{ directory.id }}'); + formData.append('dzfilename', file.name); + }); + + this.on('success', function(file, response) { + if (file.upload.chunked && file.upload.chunkIndex < file.upload.totalChunkCount - 1) { + return; + } + var formData = new FormData(); + formData.append('parent_id', '{{ directory.id }}'); + formData.append('dzuuid', file.upload.uuid); + formData.append('filename', file.name); + formData.append('dztotalchunkcount', file.upload.totalChunkCount); + fetch('/upload/chunk/finalize', { + method: 'POST', + body: formData, + }) + .then(function(r) { return r.json(); }) + .then(function(data) { + console.log('finalize response:', JSON.stringify(data)); + afterUpload(file, data); + }) + .catch(function(err) { + console.error('Finalize error:', err); + }); }); - this.on('complete', function(file) { + this.on('error', function(file, message) { + var warning = "
Upload failed for " + file.name + ": " + (typeof message === 'object' ? (message.error || JSON.stringify(message)) : message) + "
"; + $('#upload').after(warning); this.removeFile(file); }); } diff --git a/gallery/templates/view_file.html b/gallery/templates/view_file.html index 1dc49b7..8edccf0 100644 --- a/gallery/templates/view_file.html +++ b/gallery/templates/view_file.html @@ -59,7 +59,7 @@ {% elif file.mimetype.split('/')[0] == "video" %} {% elif file.mimetype == "application/pdf" or file.mimetype == "text/plain" %} From 3708df2aca53da204afc32e91ad435c603f9e010 Mon Sep 17 00:00:00 2001 From: aln730 Date: Sat, 25 Apr 2026 20:49:18 -0400 Subject: [PATCH 6/7] oops localenv --- gallery/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gallery/__init__.py b/gallery/__init__.py index 2049b2f..ab916d0 100644 --- a/gallery/__init__.py +++ b/gallery/__init__.py @@ -57,7 +57,7 @@ if os.path.exists(os.path.join(os.getcwd(), "config.py")): app_config.from_pyfile(os.path.join(os.getcwd(), "config.py")) else: - app_config.from_pyfile(os.path.join(os.getcwd(), "localconfig.env.py")) + app_config.from_pyfile(os.path.join(os.getcwd(), "config.env.py")) app.config.update(app_config) db: SQLAlchemy = SQLAlchemy(app) From 64cf783724bd737e0f86cad2ef784f4b7d0e09bb Mon Sep 17 00:00:00 2001 From: AGawas Date: Thu, 30 Apr 2026 16:45:03 -0400 Subject: [PATCH 7/7] Decrease max file size for uploads to 5MB (#134) Reduce maximum file size limit from 10MB to 5MB. --- gallery/templates/view_dir.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gallery/templates/view_dir.html b/gallery/templates/view_dir.html index 127cf04..331702c 100644 --- a/gallery/templates/view_dir.html +++ b/gallery/templates/view_dir.html @@ -252,7 +252,7 @@ uploadMultiple: false, autoProcessQueue: false, parallelUploads: 3, - maxFilesize: 10 * 1024, + maxFilesize: 5 * 1024, chunking: true, forceChunking: true, chunkSize: 10 * 1024 * 1024,