Added search function.

This commit is contained in:
2023-08-21 21:20:27 -04:00
parent 1a16e9f763
commit d445d633b4
7 changed files with 211 additions and 77 deletions

View File

@@ -6,10 +6,11 @@ from math import ceil
import filetype
# Django imports.
from django.http import HttpResponseNotFound
from django.conf import settings
from django.shortcuts import (render,
redirect)
from django.http import HttpResponseNotFound
from django.conf import settings
from django.utils.http import urlencode
from django.shortcuts import (render,
redirect)
# Project imports.
from .utils import make_thumbnail
@@ -26,6 +27,31 @@ IMAGES_PER_PAGE = CELLS_PER_ROW * ROWS_PER_PAGE
# View functions. #
###########################################################################################
def do_recursive_search(start_path, query):
"""
Gets all images and sub-directories inside the start_path whose name matches the given query,
and then joins the results recursively by iterating in each sub-directory.
"""
# Get all sub-dirs and images that match the query.
subdirs = sorted([i.absolute() for i in start_path.iterdir() if i.is_dir() and query.lower() in i.name.lower()])
images = sorted([i for i in start_path.iterdir() if i.is_file() and filetype.is_image(str(i)) and query.lower() in i.name.lower()])
# For all sub-directories, regardless of the query.
for subdir in sorted([i for i in start_path.iterdir() if i.is_dir()]):
# Do a recursive search.
rec_subdirs, rec_images = do_recursive_search(subdir, query.lower())
# Join the results if any.
subdirs.extend(rec_subdirs)
images.extend(rec_images)
return subdirs, images
###########################################################################################
# View functions. #
###########################################################################################
def gallery_view(request, path = None):
"""
Shows a list of subdirectories and image files inside the given path.
@@ -33,6 +59,10 @@ def gallery_view(request, path = None):
"""
def list2rows(lst, cells = CELLS_PER_ROW):
"""
Converts a list into a matrix with the given amount of cells per row.
"""
rows = []
i = 0
while i < len(lst):
@@ -46,64 +76,101 @@ def gallery_view(request, path = None):
i += cells
return rows
# Get the absolute path to show if any, else show the base gallery path.
full_path = settings.GALLERY_ROOT.joinpath(path) if path is not None else settings.GALLERY_ROOT
if full_path.exists():
if full_path.is_dir():
subdirs = sorted([i for i in full_path.iterdir() if i.is_dir()])
images = sorted([i for i in full_path.iterdir() if i.is_file() and filetype.is_image(str(i))])
img_data = []
num_pages = ceil((len(images) / CELLS_PER_ROW) / ROWS_PER_PAGE)
# Get the search query from the request, if any.
search = request.GET.get('search', default = '')
if full_path.exists():
# If the path exists then check if it points to a directory or an image.
if full_path.is_dir():
if search == '':
# If there is no search query then get all images and sub-directories of the current path.
subdirs = sorted([i for i in full_path.iterdir() if i.is_dir()])
images = sorted([i for i in full_path.iterdir() if i.is_file() and filetype.is_image(str(i))])
else:
# If there is a search query then search the current directory recursively.
subdirs, images = do_recursive_search(full_path, search)
# For every sub-directory found, prepare it's name and path for rendering.
subdir_data = []
for subdir in subdirs:
subdir_data.append({
'path': '/gallery/' + str(subdir.relative_to(settings.GALLERY_ROOT)),
'name': subdir.name
})
# Get the page number to show, if any. Default to the first one if unavailable or error.
try:
page = int(request.GET.get('page', 1))
except ValueError:
page = 1
# Compute the page offset to show.
num_pages = ceil((len(images) / CELLS_PER_ROW) / ROWS_PER_PAGE)
page_offset = IMAGES_PER_PAGE * (page - 1)
# Slice the images found with the page offset and prepare them for rendering.
img_data = []
for image in images[page_offset : page_offset + IMAGES_PER_PAGE]:
# Create thumbnails as needed.
make_thumbnail(image)
img_context = {
'path': image.name,
# Get the path of the image relative to the gallery root.
rel_path = image.relative_to(settings.GALLERY_ROOT)
# For each image, prepare it's path, thumbnail path and name for rendering.
img_data.append({
'path': '/gallery/' + str(rel_path),
'name': image.name,
'thumbnail': '/thumbs/' + path + '/' + image.name if path is not None else '/thumbs/' + image.name
}
img_data.append(img_context)
print(page)
'thumbnail': '/thumbs/' + str(rel_path)
})
# Rendering context.
context = {
'path': path,
'subdirs': list2rows(subdirs),
'images': list2rows(img_data),
'pages': range(1, num_pages + 1),
'num_files': len(images),
'page': page,
'prev_page': page - 1,
'next_page': page + 1,
'num_pages': num_pages
'path': path,
'subdirs': list2rows(subdir_data),
'images': list2rows(img_data),
'pages': range(1, num_pages + 1),
'num_files': len(images),
'page': page,
'prev_page': page - 1,
'next_page': page + 1,
'num_pages': num_pages,
'search': urlencode({'search': search}) if search != '' else None,
'search_text': search
}
# Glorious success!
return render(request, 'gallery_view.html', context)
else:
# If the path points to an image, then get it's real path, and parent directory path.
image = Path('/imgs/').joinpath(path)
img_dir = settings.GALLERY_ROOT.joinpath(path).parent
# Then get all sibling images.
images = sorted([i.name for i in img_dir.iterdir() if i.is_file() and filetype.is_image(str(i))])
# Get the current image's index in it's directory.
index = images.index(image.name)
# Get the previous and next image indices.
previous = index - 1 if index > 0 else None
following = index + 1 if index < len(images) - 1 else None
# Set the current, previous and next images as the rendering context.
context = {
'image_path': image,
'prev': images[previous] if previous is not None else None,
'next': images[following] if following is not None else None
}
# Glorious success!
return render(request, 'image_view.html', context)
else:
# 404 if the path wasn't found.
return HttpResponseNotFound('Not found')