Add possiblity to share gallerie with public link
All checks were successful
Docker / build (release) Successful in 8s
All checks were successful
Docker / build (release) Successful in 8s
This commit is contained in:
parent
ed28d4a9c4
commit
2a409b54f7
12 changed files with 206 additions and 48 deletions
|
|
@ -149,6 +149,20 @@ if _db_engine == "postgres":
|
|||
"PORT": config("DB_PORT", default="5432"),
|
||||
}
|
||||
}
|
||||
elif _db_engine == "mariadb":
|
||||
DATABASES = {
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.mysql",
|
||||
"NAME": config("DB_NAME", default="photo21"),
|
||||
"USER": config("DB_USER", default="photo21"),
|
||||
"PASSWORD": config("DB_PASSWORD", default=""),
|
||||
"HOST": config("DB_HOST", default="localhost"),
|
||||
"PORT": config("DB_PORT", default="3306"),
|
||||
"OPTIONS": {
|
||||
"charset": "utf8mb4",
|
||||
},
|
||||
}
|
||||
}
|
||||
elif _db_engine == "sqlite":
|
||||
DATABASES = {
|
||||
"default": {
|
||||
|
|
@ -160,7 +174,7 @@ elif _db_engine == "sqlite":
|
|||
}
|
||||
}
|
||||
else:
|
||||
raise ValueError(f"Unknown DB_ENGINE '{_db_engine}'. Must be 'sqlite' or 'postgres'.")
|
||||
raise ValueError(f"Unknown DB_ENGINE '{_db_engine}'. Must be 'sqlite', 'postgres' or 'mariadb'.")
|
||||
|
||||
CACHES = {
|
||||
"default": {
|
||||
|
|
|
|||
24
photo21/static/copy-button.js
Normal file
24
photo21/static/copy-button.js
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
document.querySelectorAll('[data-clipboard-text]').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
var text = btn.dataset.clipboardText;
|
||||
if (navigator.clipboard) {
|
||||
navigator.clipboard.writeText(text);
|
||||
} else {
|
||||
var ta = document.createElement('textarea');
|
||||
ta.value = text;
|
||||
ta.style.position = 'fixed';
|
||||
ta.style.opacity = '0';
|
||||
document.body.appendChild(ta);
|
||||
ta.select();
|
||||
document.execCommand('copy');
|
||||
document.body.removeChild(ta);
|
||||
}
|
||||
var original = btn.textContent;
|
||||
btn.textContent = '✓ Copied!';
|
||||
btn.disabled = true;
|
||||
setTimeout(function() {
|
||||
btn.textContent = original;
|
||||
btn.disabled = false;
|
||||
}, 2000);
|
||||
});
|
||||
});
|
||||
|
|
@ -37,6 +37,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
|||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
{% if request.user.is_authenticated %}
|
||||
<li class="nav-item">
|
||||
{% url 'photologue:pl-gallery-archive' as url %}
|
||||
<a class="nav-link {% if request.path_info == url %}active{% endif %}" href="{{ url }}">{% trans 'Galleries' %}</a>
|
||||
|
|
@ -52,6 +53,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
|||
<a class="nav-link" href="{% url 'admin:index' %}">{% trans 'Manage' %}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
<ul class="navbar-nav">
|
||||
{% get_available_languages as LANGUAGES %}
|
||||
|
|
|
|||
|
|
@ -9,14 +9,36 @@ from django.contrib.auth import get_user_model
|
|||
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||
from django.http import FileResponse, Http404
|
||||
from django.views.generic import ListView, View
|
||||
from photologue.models import Gallery
|
||||
from photologue.models import Gallery, Photo
|
||||
|
||||
|
||||
class MediaAccess(View):
|
||||
def get(self, request, path):
|
||||
if not request.user.is_authenticated and not request.session.get('public_gallery_access'):
|
||||
if not request.user.is_authenticated:
|
||||
from django.contrib.auth.views import redirect_to_login
|
||||
return redirect_to_login(request.get_full_path())
|
||||
try:
|
||||
allowed_ids = set(request.get_signed_cookie("public_galleries", default="").split(","))
|
||||
except Exception:
|
||||
allowed_ids = set()
|
||||
allowed_ids.discard("")
|
||||
if not allowed_ids:
|
||||
return redirect_to_login(request.get_full_path())
|
||||
# Direct match (original photo file)
|
||||
allowed = Photo.objects.filter(
|
||||
image=path,
|
||||
is_public=True,
|
||||
galleries__id__in=allowed_ids,
|
||||
).exists()
|
||||
# Cache files (thumbnails/display) are derived from original photos
|
||||
if not allowed and '/cache/' in path:
|
||||
original_dir = os.path.dirname(os.path.dirname(path))
|
||||
allowed = Photo.objects.filter(
|
||||
image__startswith=original_dir + '/',
|
||||
is_public=True,
|
||||
galleries__id__in=allowed_ids,
|
||||
).exists()
|
||||
if not allowed:
|
||||
return redirect_to_login(request.get_full_path())
|
||||
media_root = os.path.realpath(settings.MEDIA_ROOT)
|
||||
file_path = os.path.realpath(os.path.join(media_root, path))
|
||||
if not file_path.startswith(media_root + os.sep):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue