photo-objects 0.0.7__py3-none-any.whl → 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- photo_objects/django/api/album.py +21 -0
- photo_objects/django/management/commands/create-site-albums.py +4 -8
- photo_objects/django/signals.py +32 -1
- photo_objects/django/tests/test_album.py +23 -0
- photo_objects/django/views/ui/album.py +6 -2
- photo_objects/django/views/ui/configuration.py +1 -1
- {photo_objects-0.0.7.dist-info → photo_objects-0.1.0.dist-info}/METADATA +1 -1
- {photo_objects-0.0.7.dist-info → photo_objects-0.1.0.dist-info}/RECORD +11 -11
- {photo_objects-0.0.7.dist-info → photo_objects-0.1.0.dist-info}/WHEEL +0 -0
- {photo_objects-0.0.7.dist-info → photo_objects-0.1.0.dist-info}/licenses/LICENSE +0 -0
- {photo_objects-0.0.7.dist-info → photo_objects-0.1.0.dist-info}/top_level.txt +0 -0
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
from django.contrib.sites.models import Site
|
|
1
4
|
from django.db.models.deletion import ProtectedError
|
|
2
5
|
from django.http import HttpRequest
|
|
3
6
|
|
|
@@ -13,6 +16,24 @@ from .utils import (
|
|
|
13
16
|
)
|
|
14
17
|
|
|
15
18
|
|
|
19
|
+
def get_site_album(site: Site) -> Album:
|
|
20
|
+
album_key = f'_site_{site.id}'
|
|
21
|
+
return Album.objects.get_or_create(
|
|
22
|
+
key=album_key,
|
|
23
|
+
defaults={
|
|
24
|
+
'title': site.name,
|
|
25
|
+
'visibility': Album.Visibility.ADMIN,
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def parse_site_id(album_key: str) -> int | None:
|
|
30
|
+
key_match = re.match(r'_site_([0-9]+)', album_key)
|
|
31
|
+
if not key_match:
|
|
32
|
+
return None
|
|
33
|
+
|
|
34
|
+
return int(key_match.group(1))
|
|
35
|
+
|
|
36
|
+
|
|
16
37
|
def get_albums(request: HttpRequest):
|
|
17
38
|
if not request.user.is_authenticated:
|
|
18
39
|
return Album.objects.filter(visibility=Album.Visibility.PUBLIC)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from django.core.management.base import BaseCommand
|
|
2
2
|
from django.contrib.sites.models import Site
|
|
3
3
|
|
|
4
|
+
from photo_objects.django.api.album import get_site_album
|
|
4
5
|
from photo_objects.django.models import Album
|
|
5
6
|
|
|
6
7
|
|
|
@@ -11,18 +12,13 @@ class Command(BaseCommand):
|
|
|
11
12
|
sites = Site.objects.all()
|
|
12
13
|
|
|
13
14
|
for site in sites:
|
|
14
|
-
|
|
15
|
-
_, created = Album.objects.get_or_create(
|
|
16
|
-
key=album_key,
|
|
17
|
-
defaults={
|
|
18
|
-
'visibility': Album.Visibility.ADMIN,
|
|
19
|
-
})
|
|
20
|
-
|
|
15
|
+
album, created = get_site_album(site)
|
|
21
16
|
if created:
|
|
22
17
|
self.stdout.write(
|
|
23
18
|
self.style.SUCCESS(
|
|
24
19
|
f'Album for site {site.domain} created:') +
|
|
25
|
-
f'\n Key: {
|
|
20
|
+
f'\n Key: {album.key}'
|
|
21
|
+
f'\n Title: {album.title}')
|
|
26
22
|
else:
|
|
27
23
|
self.stdout.write(
|
|
28
24
|
self.style.NOTICE(
|
photo_objects/django/signals.py
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
from django.contrib.sites.models import Site
|
|
1
4
|
from django.db.models.signals import post_save, post_delete
|
|
2
5
|
from django.dispatch import receiver
|
|
3
6
|
|
|
4
|
-
from .
|
|
7
|
+
from .api.album import parse_site_id, get_site_album
|
|
8
|
+
from .models import Album, Photo
|
|
5
9
|
|
|
6
10
|
|
|
7
11
|
@receiver(post_save, sender=Photo)
|
|
@@ -56,3 +60,30 @@ def update_album_on_photo_delete(sender, **kwargs):
|
|
|
56
60
|
|
|
57
61
|
if needs_save:
|
|
58
62
|
album.save()
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@receiver(post_save, sender=Site)
|
|
66
|
+
def update_album_on_site_save(sender, **kwargs):
|
|
67
|
+
site = kwargs.get('instance', None)
|
|
68
|
+
album, created = get_site_album(site)
|
|
69
|
+
|
|
70
|
+
if not created and album.title != site.name:
|
|
71
|
+
album.title = site.name
|
|
72
|
+
album.save()
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@receiver(post_save, sender=Album)
|
|
76
|
+
def update_site_on_album_save(sender, **kwargs):
|
|
77
|
+
album = kwargs.get('instance', None)
|
|
78
|
+
site_id = parse_site_id(album.key)
|
|
79
|
+
if site_id is None:
|
|
80
|
+
return
|
|
81
|
+
|
|
82
|
+
try:
|
|
83
|
+
site = Site.objects.get(id=site_id)
|
|
84
|
+
except Site.DoesNotExist:
|
|
85
|
+
return
|
|
86
|
+
|
|
87
|
+
if site.name != album.title:
|
|
88
|
+
site.name = album.title
|
|
89
|
+
site.save()
|
|
@@ -3,6 +3,7 @@ from time import sleep
|
|
|
3
3
|
|
|
4
4
|
from django.contrib.auth import get_user_model
|
|
5
5
|
from django.contrib.auth.models import Permission
|
|
6
|
+
from django.contrib.sites.models import Site
|
|
6
7
|
|
|
7
8
|
from photo_objects.django.models import Album
|
|
8
9
|
from photo_objects.img import utcnow
|
|
@@ -375,3 +376,25 @@ class AlbumViewTests(TestCase):
|
|
|
375
376
|
|
|
376
377
|
response = self.client.delete("/api/albums/copenhagen")
|
|
377
378
|
self.assertStatus(response, 204)
|
|
379
|
+
|
|
380
|
+
def test_site_config_album_title_change(self):
|
|
381
|
+
site = Site.objects.get(id=1)
|
|
382
|
+
album, _ = Album.objects.get_or_create(
|
|
383
|
+
key="_site_1",
|
|
384
|
+
defaults={
|
|
385
|
+
"title": "Site 1",
|
|
386
|
+
"visibility": Album.Visibility.ADMIN,
|
|
387
|
+
}
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
site.name = "Changed in site"
|
|
391
|
+
site.save()
|
|
392
|
+
|
|
393
|
+
album.refresh_from_db()
|
|
394
|
+
self.assertEqual(album.title, "Changed in site")
|
|
395
|
+
|
|
396
|
+
album.title = "Changed in album"
|
|
397
|
+
album.save()
|
|
398
|
+
|
|
399
|
+
site.refresh_from_db()
|
|
400
|
+
self.assertEqual(site.name, "Changed in album")
|
|
@@ -6,6 +6,7 @@ from django.urls import reverse
|
|
|
6
6
|
from django.utils.translation import gettext_lazy as _
|
|
7
7
|
|
|
8
8
|
from photo_objects.django import api
|
|
9
|
+
from photo_objects.django.api.album import parse_site_id
|
|
9
10
|
from photo_objects.django.api.utils import FormValidationFailed
|
|
10
11
|
from photo_objects.django.forms import CreateAlbumForm, ModifyAlbumForm
|
|
11
12
|
from photo_objects.django.models import Album
|
|
@@ -48,12 +49,15 @@ def new_album(request: HttpRequest):
|
|
|
48
49
|
|
|
49
50
|
|
|
50
51
|
def get_info(request: HttpRequest, album_key: str):
|
|
51
|
-
|
|
52
|
+
site_id = parse_site_id(album_key)
|
|
53
|
+
if site_id is not None and request.site:
|
|
52
54
|
return (
|
|
53
55
|
"This is a special album for configuring site metadata for "
|
|
54
56
|
f"{request.site.name}. Use album title to override the site name, "
|
|
55
57
|
"albums cover photo to configure the preview image, and album "
|
|
56
|
-
"description to configure the site description."
|
|
58
|
+
"description to configure the site description. The album title "
|
|
59
|
+
"is automatically updated when the related sites name is changed "
|
|
60
|
+
"and vice versa.")
|
|
57
61
|
|
|
58
62
|
|
|
59
63
|
@json_problem_as_html
|
|
@@ -44,7 +44,7 @@ def uses_https(request: HttpRequest) -> Validation:
|
|
|
44
44
|
detail += _(
|
|
45
45
|
' If you are running the API server behind a reverse proxy or '
|
|
46
46
|
'a load-balancer, ensure that HTTPS termination is configured '
|
|
47
|
-
f'correctly.
|
|
47
|
+
f'correctly.')
|
|
48
48
|
|
|
49
49
|
return Validation(
|
|
50
50
|
check=_("Site is served over HTTPS"),
|
|
@@ -9,17 +9,17 @@ photo_objects/django/context_processors.py,sha256=DLhLZHAvGlrpxYegaLiKEx9X7rpyZU
|
|
|
9
9
|
photo_objects/django/forms.py,sha256=VoDlyZAwiTLyNxW3rRk5bzjfPJvNuKV-wpuLGCe5TCY,6505
|
|
10
10
|
photo_objects/django/models.py,sha256=tRHBqswASWMnyz8rwiKsmHDqEvQX54ly9k8tvU7qNOM,4597
|
|
11
11
|
photo_objects/django/objsto.py,sha256=GZuoPZ1I5qX4rwEYZlOfZZiV4NQ19iknQBT6755421Y,2417
|
|
12
|
-
photo_objects/django/signals.py,sha256=
|
|
12
|
+
photo_objects/django/signals.py,sha256=NEh_pfvsSt2f7MuHIJE0uLHUkqjKH4ipAFS7tmvm9LI,2400
|
|
13
13
|
photo_objects/django/urls.py,sha256=safcovG-8G60F_1v31ZvCCtBE8d6sHUtma6d5ZQHymo,2356
|
|
14
14
|
photo_objects/django/api/__init__.py,sha256=BnEHlm3mwyBy-1xhk-NFasgZa4fjCDjtfkBUoH0puPY,62
|
|
15
|
-
photo_objects/django/api/album.py,sha256=
|
|
15
|
+
photo_objects/django/api/album.py,sha256=c5qDvy6ebIZCzggxcYgSgLBR0cco79V47nJf2OHuBj8,2486
|
|
16
16
|
photo_objects/django/api/auth.py,sha256=LfMm02_TKwrP5XFie-KzBnW3FNFWQAafBlu0UE19Gd4,1370
|
|
17
17
|
photo_objects/django/api/photo.py,sha256=NGCg_Qd4X9NAd7t6lqByK9JGsoTq8HKkyEr-HwMCimI,3838
|
|
18
18
|
photo_objects/django/api/utils.py,sha256=DgAsbvLLZxck_D6AXLsvUXJ3OguLufZ8sadmsToenJ4,5245
|
|
19
19
|
photo_objects/django/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
20
|
photo_objects/django/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
21
|
photo_objects/django/management/commands/create-initial-admin-account.py,sha256=M4qv1d_qFSGy_lDcKbyKOmfGsQt8i16Zoit9cJ6PwAU,1099
|
|
22
|
-
photo_objects/django/management/commands/create-site-albums.py,sha256=
|
|
22
|
+
photo_objects/django/management/commands/create-site-albums.py,sha256=mz99RfmczM0x7zuVRabReq4uBZXN-2Ow7VoNWARvBig,959
|
|
23
23
|
photo_objects/django/migrations/0001_initial.py,sha256=BLW-EZ38sBgDhOYyprc-h_vuPpRxA11qxt4ZuYNO1Wo,2424
|
|
24
24
|
photo_objects/django/migrations/0002_created_at_updated_at.py,sha256=7OT2VvDffAkX9XKBHVY-jvzxeIl2yU0Jr1ByCNGcUfw,1039
|
|
25
25
|
photo_objects/django/migrations/0003_admin_visibility.py,sha256=PdxPOJzr-ViRBlOYUHEEGhe0hLtDysZJdMqvbjKVpEg,529
|
|
@@ -28,7 +28,7 @@ photo_objects/django/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm
|
|
|
28
28
|
photo_objects/django/templatetags/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
29
|
photo_objects/django/templatetags/photo_objects_extras.py,sha256=LjqvVZpcVqdEQQ-EgC7OkEv2DqIvmfmDC-EsQNmkY7M,1205
|
|
30
30
|
photo_objects/django/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
|
-
photo_objects/django/tests/test_album.py,sha256=
|
|
31
|
+
photo_objects/django/tests/test_album.py,sha256=qeRx_M8EvY9n_as1x8-EWtp9Ob1kOPGnUfZuUnMfDO4,13979
|
|
32
32
|
photo_objects/django/tests/test_auth.py,sha256=su00EypNzGQcvxqhmOtFevZriK31pY7yD1HxpQFcUT4,3928
|
|
33
33
|
photo_objects/django/tests/test_photo.py,sha256=SpQsVynzJLP2F9qYrvZMzCBSiHvsRDpOZ8-W_07K_q8,13386
|
|
34
34
|
photo_objects/django/tests/test_utils.py,sha256=DkhzDtZqu5OXg-IKzqHz2GY0sFS8RbwYC3w81RuPxS4,1259
|
|
@@ -41,12 +41,12 @@ photo_objects/django/views/api/auth.py,sha256=N53csbthH0DEMFjY3fqhtLmtdL7xqzkatk
|
|
|
41
41
|
photo_objects/django/views/api/photo.py,sha256=52UMP1r6TN_xfu8fHE25yOUiTa6W1F2XbgEichM8tTE,3526
|
|
42
42
|
photo_objects/django/views/api/utils.py,sha256=uQzKdSKHRAux5OZzqgWQr0gsK_FeweQP0cg_67OWA_Y,264
|
|
43
43
|
photo_objects/django/views/ui/__init__.py,sha256=vbFXPj5liue-M_CXQGP5PKhD98Z5ev53yKLPU8zWpUs,71
|
|
44
|
-
photo_objects/django/views/ui/album.py,sha256=
|
|
45
|
-
photo_objects/django/views/ui/configuration.py,sha256=
|
|
44
|
+
photo_objects/django/views/ui/album.py,sha256=80fkAdtXjgBqq-4e1i2slnzWD2C-m6rc02piIqYlgmI,5215
|
|
45
|
+
photo_objects/django/views/ui/configuration.py,sha256=pzNRHq3FSrVCTx2R31_FW3A3aJxzEO4pDnXsOVS75uA,5576
|
|
46
46
|
photo_objects/django/views/ui/photo.py,sha256=4NJSN5X_NcVcUEPaoGEGmXRDAgI5_KsOlHr7j-yo2QY,6040
|
|
47
47
|
photo_objects/django/views/ui/utils.py,sha256=YV_YcUbX-zUkdFnBlezPChR6aPDhZJ9loSOHBSzF6Cc,273
|
|
48
|
-
photo_objects-0.0.
|
|
49
|
-
photo_objects-0.0.
|
|
50
|
-
photo_objects-0.0.
|
|
51
|
-
photo_objects-0.0.
|
|
52
|
-
photo_objects-0.0.
|
|
48
|
+
photo_objects-0.1.0.dist-info/licenses/LICENSE,sha256=V3w6hTjXfP65F4r_mejveHcV5igHrblxao3-2RlfVlA,1068
|
|
49
|
+
photo_objects-0.1.0.dist-info/METADATA,sha256=o0IEDnYB7mXHUO3cT2i-yCDCkfS01DoT8OW32U4tOxU,3671
|
|
50
|
+
photo_objects-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
51
|
+
photo_objects-0.1.0.dist-info/top_level.txt,sha256=SZeL8mhf-WMGdhRtTGFvZc3aIRBboQls9O0cFDMGdQ0,14
|
|
52
|
+
photo_objects-0.1.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|