diff --git a/NibasaViewer/settings.py b/NibasaViewer/settings.py index 2c58bb8..38b732d 100644 --- a/NibasaViewer/settings.py +++ b/NibasaViewer/settings.py @@ -104,6 +104,10 @@ AUTH_PASSWORD_VALIDATORS = [ }, ] +# Authentication. +LOGIN_REDIRECT_URL = '/gallery/' +LOGOUT_REDIRECT_URL = 'login' +LOGIN_URL = 'login' # Internationalization # https://docs.djangoproject.com/en/4.2/topics/i18n/ diff --git a/NibasaViewer/urls.py b/NibasaViewer/urls.py index 170fee0..273adc5 100644 --- a/NibasaViewer/urls.py +++ b/NibasaViewer/urls.py @@ -21,6 +21,9 @@ from django.conf.urls.static import static from django.urls import (path, include) +from django.contrib.auth import views + +# Project imports. from viewer.views import index ########################################################################################### @@ -31,8 +34,13 @@ urlpatterns = [ # Index. path('', index, name = 'home'), + # Auth views. + path("login/", views.LoginView.as_view(), name = 'login'), + path("logout/", views.LogoutView.as_view(), name = 'logout'), + # Add invoices app urls. path('gallery/', include('viewer.urls')), + ] + static(settings.STATIC_URL, document_root = settings.STATIC_ROOT)\ + static('imgs/', document_root = settings.GALLERY_ROOT)\ + static('thumbs/', document_root = settings.THUMBNAILS_ROOT) diff --git a/README.md b/README.md index 2f5a4f3..29e206a 100644 --- a/README.md +++ b/README.md @@ -4,4 +4,8 @@ A basic pure HTML+CSS gallery viewer in the vein of [PiGallery 2](https://bpatri ## User authentication. -Currently there is no authentication at all because I don't need it. This is meant to be installed in a server with HTTP basic auth enabled if needed. +To login a user should be manually created by running the following commands in the Django shell, substituting the user's name, email and password as needed: + + from django.contrib.auth.models import User + user = User.objects.create_user('', '', '') + user.save() diff --git a/viewer/static/css/styles.css b/viewer/static/css/styles.css index a29f24a..afbc60c 100644 --- a/viewer/static/css/styles.css +++ b/viewer/static/css/styles.css @@ -44,6 +44,10 @@ body { width: 100%; } +.pd { + padding: 10%; +} + /**************************************************************************** * Content. * ****************************************************************************/ @@ -83,7 +87,7 @@ body { margin-left: 2em; } -.search-btn { +.clear-btn { border: none; background-color: #00000000; } @@ -92,6 +96,10 @@ body { height: 2.5em; } +.float-right { + float: right; +} + /**************************************************************************** * Grid. * ****************************************************************************/ diff --git a/viewer/static/imgs/boot.png b/viewer/static/imgs/boot.png new file mode 100755 index 0000000..d32bd98 Binary files /dev/null and b/viewer/static/imgs/boot.png differ diff --git a/viewer/templates/gallery_view.html b/viewer/templates/gallery_view.html index 649714e..a7f1dbe 100644 --- a/viewer/templates/gallery_view.html +++ b/viewer/templates/gallery_view.html @@ -43,11 +43,21 @@ {% if num_pages > 1 %} -
+
{% for page in pages %}{{page}}{% if not forloop.last %} {% endif %}{% endfor %}
{% endif %} + + + +
+ {% csrf_token %} + +
+ @@ -70,7 +80,7 @@ - diff --git a/viewer/templates/registration/login.html b/viewer/templates/registration/login.html new file mode 100644 index 0000000..0232546 --- /dev/null +++ b/viewer/templates/registration/login.html @@ -0,0 +1,42 @@ +{% load static %} + + + + + + NibasaViewer login + + + + + +
+
+ {% csrf_token %} + + + + + + + + + + +
+ {{ form.username.label_tag }} + + {{ form.username }} +
+ {{ form.password.label_tag }} + + {{ form.password }} +
+ + + +
+
+ + + diff --git a/viewer/views.py b/viewer/views.py index 32e72b5..2f4e19b 100644 --- a/viewer/views.py +++ b/viewer/views.py @@ -6,11 +6,15 @@ from math import ceil import filetype # Django imports. -from django.http import HttpResponseNotFound -from django.conf import settings -from django.utils.http import urlencode -from django.shortcuts import (render, - redirect) +from django.http import HttpResponseNotFound +from django.conf import settings +from django.utils.http import urlencode +from django.contrib.auth.decorators import login_required +from django.contrib.auth import (authenticate, + login, + logout) +from django.shortcuts import (render, + redirect) # Project imports. from .utils import make_thumbnail @@ -24,12 +28,9 @@ ROWS_PER_PAGE = 4 IMAGES_PER_PAGE = CELLS_PER_ROW * ROWS_PER_PAGE ########################################################################################### -# View functions. # +# Helper functions. # ########################################################################################### -def index(request): - return redirect('gallery_view_root') - def do_recursive_search(start_path, query): """ Gets all images and sub-directories inside the start_path whose name matches the given query, @@ -56,6 +57,11 @@ def do_recursive_search(start_path, query): # View functions. # ########################################################################################### +@login_required +def index(request): + return redirect('gallery_view_root') + +@login_required def gallery_view(request, path = None): """ Shows a list of subdirectories and image files inside the given path.