Added search function.
This commit is contained in:
121
viewer/views.py
121
viewer/views.py
@@ -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')
|
||||
|
Reference in New Issue
Block a user