photo-objects 0.9.5__py3-none-any.whl → 0.10.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/photo.py +0 -48
- photo_objects/django/api/utils.py +2 -7
- photo_objects/django/forms.py +0 -26
- photo_objects/django/tests/test_utils.py +3 -2
- photo_objects/django/urls.py +5 -1
- photo_objects/django/views/ui/album.py +25 -9
- photo_objects/django/views/ui/configuration.py +16 -6
- photo_objects/django/views/ui/photo.py +19 -30
- photo_objects/django/views/ui/photo_change_request.py +6 -5
- photo_objects/django/views/ui/users.py +4 -6
- photo_objects/django/views/ui/utils.py +15 -0
- photo_objects/django/views/utils.py +49 -5
- {photo_objects-0.9.5.dist-info → photo_objects-0.10.0.dist-info}/METADATA +1 -1
- {photo_objects-0.9.5.dist-info → photo_objects-0.10.0.dist-info}/RECORD +17 -17
- {photo_objects-0.9.5.dist-info → photo_objects-0.10.0.dist-info}/WHEEL +0 -0
- {photo_objects-0.9.5.dist-info → photo_objects-0.10.0.dist-info}/licenses/LICENSE +0 -0
- {photo_objects-0.9.5.dist-info → photo_objects-0.10.0.dist-info}/top_level.txt +0 -0
|
@@ -9,7 +9,6 @@ from photo_objects.django import objsto
|
|
|
9
9
|
from photo_objects.django.forms import (
|
|
10
10
|
CreatePhotoForm,
|
|
11
11
|
ModifyPhotoForm,
|
|
12
|
-
UploadPhotosForm,
|
|
13
12
|
slugify,
|
|
14
13
|
)
|
|
15
14
|
from photo_objects.img import photo_details
|
|
@@ -17,7 +16,6 @@ from photo_objects.img import photo_details
|
|
|
17
16
|
from .auth import check_album_access, check_photo_access
|
|
18
17
|
from .utils import (
|
|
19
18
|
FormValidationFailed,
|
|
20
|
-
UploadPhotosFailed,
|
|
21
19
|
JsonProblem,
|
|
22
20
|
check_permissions,
|
|
23
21
|
parse_input_data,
|
|
@@ -74,52 +72,6 @@ def upload_photo(request: HttpRequest, album_key: str):
|
|
|
74
72
|
return _upload_photo(album_key, photo_file)
|
|
75
73
|
|
|
76
74
|
|
|
77
|
-
def _join_errors(errors: dict) -> str:
|
|
78
|
-
messages = []
|
|
79
|
-
for _, errs in errors.items():
|
|
80
|
-
for err in errs:
|
|
81
|
-
try:
|
|
82
|
-
messages.append(err.get('message'))
|
|
83
|
-
except AttributeError:
|
|
84
|
-
messages.append(str(err))
|
|
85
|
-
return " ".join(messages) if messages else "Unknown error."
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
def upload_photos(request: HttpRequest, album_key: str):
|
|
89
|
-
check_permissions(
|
|
90
|
-
request,
|
|
91
|
-
'photo_objects.add_photo',
|
|
92
|
-
'photo_objects.change_album')
|
|
93
|
-
|
|
94
|
-
f = UploadPhotosForm(request.POST, request.FILES)
|
|
95
|
-
if not f.is_valid():
|
|
96
|
-
raise FormValidationFailed(f)
|
|
97
|
-
|
|
98
|
-
photo_files = f.cleaned_data["photos"]
|
|
99
|
-
if len(photo_files) < 1:
|
|
100
|
-
f.add_error("photos", "Expected at least one file, got 0.")
|
|
101
|
-
raise FormValidationFailed(f)
|
|
102
|
-
|
|
103
|
-
photos = []
|
|
104
|
-
for photo_file in f.cleaned_data["photos"]:
|
|
105
|
-
try:
|
|
106
|
-
photos.append(_upload_photo(album_key, photo_file))
|
|
107
|
-
except FormValidationFailed as e:
|
|
108
|
-
message = _join_errors(e.form.errors.get_json_data())
|
|
109
|
-
f.add_error(
|
|
110
|
-
"photos",
|
|
111
|
-
f"Failed to upload {photo_file.name}. {message}")
|
|
112
|
-
except JsonProblem as e:
|
|
113
|
-
f.add_error(
|
|
114
|
-
"photos",
|
|
115
|
-
f"Failed to upload {photo_file.name}. {e.title}")
|
|
116
|
-
|
|
117
|
-
if not f.is_valid():
|
|
118
|
-
raise UploadPhotosFailed(f, [i.filename for i in photos])
|
|
119
|
-
|
|
120
|
-
return photos
|
|
121
|
-
|
|
122
|
-
|
|
123
75
|
def modify_photo(request: HttpRequest, album_key: str, photo_key: str):
|
|
124
76
|
check_permissions(request, 'photo_objects.change_photo')
|
|
125
77
|
photo = check_photo_access(request, album_key, photo_key, 'xs')
|
|
@@ -53,7 +53,8 @@ class JsonProblem(PhotoObjectsError):
|
|
|
53
53
|
'Albums',
|
|
54
54
|
reverse_lazy('photo_objects:list_albums')),
|
|
55
55
|
"problem_title": self.title,
|
|
56
|
-
"status": self.status
|
|
56
|
+
"status": self.status,
|
|
57
|
+
"width": "narrow",
|
|
57
58
|
}, status=self.status)
|
|
58
59
|
|
|
59
60
|
|
|
@@ -137,12 +138,6 @@ class FormValidationFailed(JsonProblem):
|
|
|
137
138
|
self.form = form
|
|
138
139
|
|
|
139
140
|
|
|
140
|
-
class UploadPhotosFailed(FormValidationFailed):
|
|
141
|
-
def __init__(self, form: ModelForm, uploaded_photos: list[str]):
|
|
142
|
-
super().__init__(form)
|
|
143
|
-
self.uploaded_photos = uploaded_photos
|
|
144
|
-
|
|
145
|
-
|
|
146
141
|
def check_permissions(request: HttpRequest, *permissions: str):
|
|
147
142
|
if not request.user.is_authenticated:
|
|
148
143
|
raise Unauthorized()
|
photo_objects/django/forms.py
CHANGED
|
@@ -3,9 +3,6 @@ import random
|
|
|
3
3
|
from django import forms
|
|
4
4
|
from django.forms import (
|
|
5
5
|
CharField,
|
|
6
|
-
ClearableFileInput,
|
|
7
|
-
FileField,
|
|
8
|
-
Form,
|
|
9
6
|
HiddenInput,
|
|
10
7
|
ModelForm,
|
|
11
8
|
RadioSelect,
|
|
@@ -220,26 +217,3 @@ class ReviewPhotoChangeRequestForm(ModelForm):
|
|
|
220
217
|
help_texts = {
|
|
221
218
|
'alt_text': ALT_TEXT_HELP,
|
|
222
219
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
class MultipleFileInput(ClearableFileInput):
|
|
226
|
-
allow_multiple_selected = True
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
class MultipleFileField(FileField):
|
|
230
|
-
def __init__(self, *args, **kwargs):
|
|
231
|
-
kwargs.setdefault('widget', MultipleFileInput())
|
|
232
|
-
super().__init__(*args, **kwargs)
|
|
233
|
-
|
|
234
|
-
def clean(self, data, initial=None):
|
|
235
|
-
single_file_clean = super().clean
|
|
236
|
-
if isinstance(data, (list, tuple)):
|
|
237
|
-
result = [single_file_clean(d, initial) for d in data]
|
|
238
|
-
else:
|
|
239
|
-
result = [single_file_clean(data, initial)]
|
|
240
|
-
return result
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
class UploadPhotosForm(Form):
|
|
244
|
-
photos = MultipleFileField(label=_(
|
|
245
|
-
'Drag and drop photos here or click to open upload dialog.'))
|
|
@@ -56,8 +56,9 @@ class TestUtils(TestCase):
|
|
|
56
56
|
"Plain text description"),
|
|
57
57
|
(md_multi_p,
|
|
58
58
|
"Description with bold and italics..."),
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
# TODO: Test default description and description from site-settings
|
|
60
|
+
# (None,
|
|
61
|
+
# "A simple self-hosted photo server."),
|
|
61
62
|
]
|
|
62
63
|
|
|
63
64
|
for description, expected in testdata:
|
photo_objects/django/urls.py
CHANGED
|
@@ -9,7 +9,11 @@ urlpatterns = [
|
|
|
9
9
|
path("_auth", api.has_permission),
|
|
10
10
|
path("api/albums", api.albums),
|
|
11
11
|
path("api/albums/<str:album_key>", api.album),
|
|
12
|
-
path(
|
|
12
|
+
path(
|
|
13
|
+
"api/albums/<str:album_key>/photos",
|
|
14
|
+
api.photos,
|
|
15
|
+
name="api_photos",
|
|
16
|
+
),
|
|
13
17
|
path("api/albums/<str:album_key>/photos/<str:photo_key>", api.photo),
|
|
14
18
|
path(
|
|
15
19
|
"api/albums/<str:album_key>/photos/<str:photo_key>/change-requests",
|
|
@@ -9,11 +9,12 @@ from photo_objects.django.forms import CreateAlbumForm, ModifyAlbumForm
|
|
|
9
9
|
from photo_objects.django.models import Album
|
|
10
10
|
from photo_objects.django.views.utils import (
|
|
11
11
|
BackLink,
|
|
12
|
+
Preview,
|
|
12
13
|
meta_description,
|
|
13
14
|
)
|
|
14
15
|
from photo_objects.utils import render_markdown
|
|
15
16
|
|
|
16
|
-
from .utils import json_problem_as_html
|
|
17
|
+
from .utils import json_problem_as_html, preview_helptext
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
@json_problem_as_html
|
|
@@ -46,6 +47,7 @@ def new_album(request: HttpRequest):
|
|
|
46
47
|
"form": form,
|
|
47
48
|
"title": "Create album",
|
|
48
49
|
"back": back,
|
|
50
|
+
"width": "narrow",
|
|
49
51
|
})
|
|
50
52
|
|
|
51
53
|
|
|
@@ -106,14 +108,24 @@ def edit_album(request: HttpRequest, album_key: str):
|
|
|
106
108
|
reverse(
|
|
107
109
|
'photo_objects:show_album',
|
|
108
110
|
kwargs={"album_key": album_key}))
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
111
|
+
empty = album.cover_photo is None
|
|
112
|
+
|
|
113
|
+
return render(
|
|
114
|
+
request,
|
|
115
|
+
'photo_objects/form.html',
|
|
116
|
+
{
|
|
117
|
+
"form": form,
|
|
118
|
+
"title": "Edit album",
|
|
119
|
+
"back": back,
|
|
120
|
+
"info": get_info(
|
|
121
|
+
request,
|
|
122
|
+
album_key),
|
|
123
|
+
"width": "narrow",
|
|
124
|
+
"preview": Preview(
|
|
125
|
+
request,
|
|
126
|
+
album,
|
|
127
|
+
preview_helptext("album", empty)),
|
|
128
|
+
})
|
|
117
129
|
|
|
118
130
|
|
|
119
131
|
@json_problem_as_html
|
|
@@ -140,10 +152,14 @@ def delete_album(request: HttpRequest, album_key: str):
|
|
|
140
152
|
error = {'error': _(
|
|
141
153
|
'This album is managed by the system and can not be deleted.')}
|
|
142
154
|
|
|
155
|
+
empty = album.cover_photo is None
|
|
156
|
+
|
|
143
157
|
return render(request, 'photo_objects/delete.html', {
|
|
144
158
|
"title": "Delete album",
|
|
145
159
|
"back": back,
|
|
146
160
|
"photo": album.cover_photo,
|
|
147
161
|
"resource": target,
|
|
162
|
+
"width": "narrow",
|
|
163
|
+
"preview": Preview(request, album, preview_helptext("album", empty)),
|
|
148
164
|
**error,
|
|
149
165
|
})
|
|
@@ -6,7 +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.api.utils import JsonProblem
|
|
9
|
-
from photo_objects.django.views.utils import BackLink
|
|
9
|
+
from photo_objects.django.views.utils import BackLink, Preview
|
|
10
10
|
from photo_objects.utils import render_markdown
|
|
11
11
|
|
|
12
12
|
from .utils import json_problem_as_html
|
|
@@ -169,8 +169,18 @@ def configuration(request: HttpRequest):
|
|
|
169
169
|
|
|
170
170
|
back = BackLink("Albums", reverse('photo_objects:list_albums'))
|
|
171
171
|
|
|
172
|
-
return render(
|
|
173
|
-
|
|
174
|
-
"
|
|
175
|
-
|
|
176
|
-
|
|
172
|
+
return render(
|
|
173
|
+
request,
|
|
174
|
+
"photo_objects/configuration.html",
|
|
175
|
+
{
|
|
176
|
+
"title": "Configuration",
|
|
177
|
+
"validations": validations,
|
|
178
|
+
"back": back,
|
|
179
|
+
"width": "narrow",
|
|
180
|
+
"preview": Preview(
|
|
181
|
+
request,
|
|
182
|
+
None,
|
|
183
|
+
"This is an example on how the site will appear by default "
|
|
184
|
+
"when sharing in social media. Note that individual albums "
|
|
185
|
+
"and photos override this default preview."),
|
|
186
|
+
})
|
|
@@ -6,53 +6,36 @@ from photo_objects.django import api
|
|
|
6
6
|
from photo_objects.django.api.utils import (
|
|
7
7
|
AlbumNotFound,
|
|
8
8
|
FormValidationFailed,
|
|
9
|
-
UploadPhotosFailed,
|
|
10
9
|
)
|
|
11
|
-
from photo_objects.django.forms import ModifyPhotoForm
|
|
10
|
+
from photo_objects.django.forms import ModifyPhotoForm
|
|
12
11
|
from photo_objects.django.models import Photo
|
|
13
12
|
from photo_objects.django.views.utils import (
|
|
14
13
|
BackLink,
|
|
14
|
+
Preview,
|
|
15
15
|
meta_description,
|
|
16
16
|
)
|
|
17
17
|
from photo_objects.utils import render_markdown
|
|
18
18
|
|
|
19
|
-
from .utils import json_problem_as_html
|
|
19
|
+
from .utils import json_problem_as_html, preview_helptext
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
@json_problem_as_html
|
|
23
23
|
def upload_photos(request: HttpRequest, album_key: str):
|
|
24
|
-
if request.method == "POST":
|
|
25
|
-
try:
|
|
26
|
-
api.upload_photos(request, album_key)
|
|
27
|
-
return HttpResponseRedirect(
|
|
28
|
-
reverse(
|
|
29
|
-
'photo_objects:show_album',
|
|
30
|
-
kwargs={"album_key": album_key}))
|
|
31
|
-
except UploadPhotosFailed as e:
|
|
32
|
-
form = e.form
|
|
33
|
-
uploaded_count = len(e.uploaded_photos)
|
|
34
|
-
if uploaded_count > 0:
|
|
35
|
-
plural = 's' if uploaded_count != 1 else ''
|
|
36
|
-
info = f"Successfully uploaded {uploaded_count} photo{plural}."
|
|
37
|
-
else:
|
|
38
|
-
info = None
|
|
39
|
-
else:
|
|
40
|
-
form = UploadPhotosForm()
|
|
41
|
-
info = None
|
|
42
|
-
|
|
43
24
|
album = api.check_album_access(request, album_key)
|
|
44
25
|
target = album.title or album.key
|
|
45
26
|
back = BackLink(
|
|
46
27
|
target, reverse(
|
|
47
28
|
'photo_objects:show_album', kwargs={
|
|
48
29
|
"album_key": album_key}))
|
|
30
|
+
empty = album.cover_photo is None
|
|
49
31
|
|
|
50
32
|
return render(request, 'photo_objects/photo/upload.html', {
|
|
51
|
-
"form": form,
|
|
52
|
-
"info": info,
|
|
53
33
|
"title": "Upload photos",
|
|
54
34
|
"back": back,
|
|
35
|
+
"album": album,
|
|
55
36
|
"photo": album.cover_photo,
|
|
37
|
+
"width": "narrow",
|
|
38
|
+
"preview": Preview(request, album, preview_helptext("album", empty)),
|
|
56
39
|
})
|
|
57
40
|
|
|
58
41
|
|
|
@@ -177,12 +160,16 @@ def edit_photo(request: HttpRequest, album_key: str, photo_key: str):
|
|
|
177
160
|
"album_key": album_key,
|
|
178
161
|
"photo_key": photo_key}))
|
|
179
162
|
|
|
180
|
-
return render(
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
163
|
+
return render(
|
|
164
|
+
request,
|
|
165
|
+
'photo_objects/form.html',
|
|
166
|
+
{
|
|
167
|
+
"form": form,
|
|
168
|
+
"title": "Edit photo",
|
|
169
|
+
"back": back,
|
|
170
|
+
"width": "narrow",
|
|
171
|
+
"preview": Preview(request, photo, preview_helptext("photo")),
|
|
172
|
+
})
|
|
186
173
|
|
|
187
174
|
|
|
188
175
|
@json_problem_as_html
|
|
@@ -208,4 +195,6 @@ def delete_photo(request: HttpRequest, album_key: str, photo_key: str):
|
|
|
208
195
|
"back": back,
|
|
209
196
|
"photo": photo,
|
|
210
197
|
"resource": target,
|
|
198
|
+
"width": "narrow",
|
|
199
|
+
"preview": Preview(request, photo, preview_helptext("photo")),
|
|
211
200
|
})
|
|
@@ -7,7 +7,7 @@ from photo_objects.django.api.utils import (
|
|
|
7
7
|
FormValidationFailed,
|
|
8
8
|
)
|
|
9
9
|
from photo_objects.django.forms import ReviewPhotoChangeRequestForm
|
|
10
|
-
from photo_objects.django.views.utils import BackLink
|
|
10
|
+
from photo_objects.django.views.utils import BackLink, Preview
|
|
11
11
|
from photo_objects.utils import render_markdown
|
|
12
12
|
|
|
13
13
|
from .utils import json_problem_as_html
|
|
@@ -49,13 +49,14 @@ def review_photo_change_request(request: HttpRequest, cr_id: str):
|
|
|
49
49
|
|
|
50
50
|
back = BackLink("Albums", reverse('photo_objects:list_albums'))
|
|
51
51
|
|
|
52
|
+
helptext = render_markdown(
|
|
53
|
+
f'The current alt text for `{photo.key}` is: _"{photo.alt_text}"_.')
|
|
54
|
+
|
|
52
55
|
return render(request, 'photo_objects/form.html', {
|
|
53
56
|
"form": form,
|
|
54
57
|
"title": "Review photo change request",
|
|
55
58
|
"back": back,
|
|
56
|
-
"photo": photo,
|
|
57
59
|
"info": info,
|
|
58
|
-
"
|
|
59
|
-
|
|
60
|
-
f'_"{photo.alt_text}"_.'),
|
|
60
|
+
"width": "narrow",
|
|
61
|
+
"preview": Preview(request, photo, helptext),
|
|
61
62
|
})
|
|
@@ -2,22 +2,20 @@ from django.contrib.auth import views as auth_views
|
|
|
2
2
|
from django.http import HttpRequest
|
|
3
3
|
from django.urls import reverse_lazy
|
|
4
4
|
|
|
5
|
-
from photo_objects.django.
|
|
6
|
-
from photo_objects.django.views.utils import BackLink
|
|
5
|
+
from photo_objects.django.views.utils import BackLink, Preview
|
|
7
6
|
|
|
8
7
|
|
|
9
8
|
def login(request: HttpRequest):
|
|
10
|
-
settings = SiteSettings.objects.get(request.site)
|
|
11
|
-
|
|
12
9
|
return auth_views.LoginView.as_view(
|
|
13
10
|
template_name="photo_objects/form.html",
|
|
14
11
|
extra_context={
|
|
15
12
|
"title": "Login",
|
|
16
|
-
"photo": settings.preview_image,
|
|
17
13
|
"action": "Login",
|
|
18
14
|
"back": BackLink(
|
|
19
15
|
'Albums',
|
|
20
16
|
reverse_lazy('photo_objects:list_albums')),
|
|
21
|
-
"class": "login"
|
|
17
|
+
"class": "login",
|
|
18
|
+
"width": "narrow",
|
|
19
|
+
"preview": Preview(request, None),
|
|
22
20
|
},
|
|
23
21
|
)(request)
|
|
@@ -8,3 +8,18 @@ def json_problem_as_html(func):
|
|
|
8
8
|
except JsonProblem as e:
|
|
9
9
|
return e.html_response(args[0])
|
|
10
10
|
return wrapper
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def preview_helptext(resource_type: str, empty: bool = False) -> str:
|
|
14
|
+
if resource_type == "album" and empty:
|
|
15
|
+
return (
|
|
16
|
+
f"This is an example on how the {resource_type} would appear "
|
|
17
|
+
"when sharing on social media. Upload photos and select a cover "
|
|
18
|
+
"photo to use this album specific preview instead of the server "
|
|
19
|
+
"level default preview."
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
f"This is an example on how the {resource_type} will currently appear "
|
|
24
|
+
"when sharing on social media."
|
|
25
|
+
)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from django.http import HttpRequest
|
|
2
2
|
from django.utils.dateformat import format as format_date
|
|
3
3
|
|
|
4
|
-
from photo_objects.django.models import Album, Photo
|
|
4
|
+
from photo_objects.django.models import Album, Photo, SiteSettings
|
|
5
5
|
from photo_objects.utils import first_paragraph_textcontent
|
|
6
6
|
|
|
7
7
|
|
|
@@ -11,6 +11,19 @@ class BackLink:
|
|
|
11
11
|
self.url = url
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
# TODO: Use this also for meta-og tags
|
|
15
|
+
class Preview:
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
request: HttpRequest,
|
|
19
|
+
resource: Album | Photo = None,
|
|
20
|
+
helptext: str = None):
|
|
21
|
+
self.description = meta_description(request, resource)
|
|
22
|
+
self.photo = meta_photo(request, resource)
|
|
23
|
+
self.title = meta_title(request, resource)
|
|
24
|
+
self.helptext = helptext
|
|
25
|
+
|
|
26
|
+
|
|
14
27
|
def _default_album_description(request: HttpRequest, album: Album) -> str:
|
|
15
28
|
count = album.photo_set.count()
|
|
16
29
|
plural = 's' if count != 1 else ''
|
|
@@ -24,19 +37,50 @@ def _default_photo_description(photo: Photo) -> str:
|
|
|
24
37
|
|
|
25
38
|
def meta_description(
|
|
26
39
|
request: HttpRequest,
|
|
27
|
-
resource: Album | Photo | str
|
|
40
|
+
resource: Album | Photo | str = None) -> str:
|
|
28
41
|
text = None
|
|
29
42
|
if isinstance(resource, Album):
|
|
30
|
-
|
|
43
|
+
return (
|
|
31
44
|
first_paragraph_textcontent(resource.description) or
|
|
32
45
|
_default_album_description(request, resource))
|
|
33
46
|
|
|
34
47
|
if isinstance(resource, Photo):
|
|
35
|
-
|
|
48
|
+
return (
|
|
36
49
|
first_paragraph_textcontent(resource.description) or
|
|
37
50
|
_default_photo_description(resource))
|
|
38
51
|
|
|
39
52
|
if isinstance(resource, str):
|
|
40
|
-
|
|
53
|
+
return first_paragraph_textcontent(resource)
|
|
41
54
|
|
|
55
|
+
settings = SiteSettings.objects.get(request.site)
|
|
56
|
+
text = first_paragraph_textcontent(settings.description)
|
|
42
57
|
return text or "A simple self-hosted photo server."
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def meta_photo(
|
|
61
|
+
request: HttpRequest,
|
|
62
|
+
resource: Album | Photo = None) -> Photo:
|
|
63
|
+
if isinstance(resource, Photo):
|
|
64
|
+
return resource
|
|
65
|
+
|
|
66
|
+
if isinstance(resource, Album):
|
|
67
|
+
return resource.cover_photo
|
|
68
|
+
|
|
69
|
+
settings = SiteSettings.objects.get(request.site)
|
|
70
|
+
return settings.preview_image
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def meta_title(
|
|
74
|
+
request: HttpRequest,
|
|
75
|
+
resource: Album | Photo | str = None) -> str:
|
|
76
|
+
text = None
|
|
77
|
+
if isinstance(resource, Album):
|
|
78
|
+
text = resource.title
|
|
79
|
+
|
|
80
|
+
if isinstance(resource, Photo):
|
|
81
|
+
text = resource.title or resource.filename
|
|
82
|
+
|
|
83
|
+
if isinstance(resource, str):
|
|
84
|
+
text = resource
|
|
85
|
+
|
|
86
|
+
return text or request.site.name
|
|
@@ -8,18 +8,18 @@ photo_objects/django/admin.py,sha256=pvyQKs2FMtKtSS2PE_NKR_jsSi7-GKz3bbsqDNgjt6w
|
|
|
8
8
|
photo_objects/django/apps.py,sha256=Apqu6o6fpoxda18NQgKupvQRvTAZxVviIK_-dUR3rck,1444
|
|
9
9
|
photo_objects/django/conf.py,sha256=ZpeIulEc1tpr8AO52meNKOF30Xf5osbDtDyHvQRtkx4,2593
|
|
10
10
|
photo_objects/django/context_processors.py,sha256=XacUmcYV-4NMMMNXPWrHKdvNd6lfyamisngaVerREiU,306
|
|
11
|
-
photo_objects/django/forms.py,sha256=
|
|
11
|
+
photo_objects/django/forms.py,sha256=HIkDRQhSMzvj0D4BdKEuEndB3bV-3NTH_h0gMRQ9UlQ,6123
|
|
12
12
|
photo_objects/django/models.py,sha256=OxkkczIBg7TaFWWm4VdtbRMJOK_OQKrV29g-X2cm5BQ,7247
|
|
13
13
|
photo_objects/django/objsto.py,sha256=kf-Tv-kDt47Mnx0xMolAct_lP4M0H9xg03M3BnfAnJM,6909
|
|
14
14
|
photo_objects/django/signals.py,sha256=_gb4vlZkeFNYWXxwhNreaUJoOsbIWvP8OovVLtzepaE,2161
|
|
15
|
-
photo_objects/django/urls.py,sha256=
|
|
15
|
+
photo_objects/django/urls.py,sha256=QHGjDj3XCArLtmMcP3DKp8H9Xfd2X4SEvEKmMnx2KDk,2551
|
|
16
16
|
photo_objects/django/api/__init__.py,sha256=51CRTiE975ufVhvI5x-M_2D28JP8FZWyLFiuV5EaQSg,120
|
|
17
17
|
photo_objects/django/api/album.py,sha256=CJDeGLCuYoxGUDcjssZRpFnToxG_KVE9Ii7NduFW2ks,2003
|
|
18
18
|
photo_objects/django/api/auth.py,sha256=lS0S1tMVH2uN30g4jlixklv3eMnQ2FbQVQvuRXeMGYo,1420
|
|
19
19
|
photo_objects/django/api/backup.py,sha256=lu-lDSGpEV9ASCIA5o0kNOZcg6_cmkVPCy1TFRvYyyY,6344
|
|
20
|
-
photo_objects/django/api/photo.py,sha256
|
|
20
|
+
photo_objects/django/api/photo.py,sha256=GtrLMQAQRDQa79cAiEnYVeZ9Wr9CIpHC9ApDqAh5uiQ,2999
|
|
21
21
|
photo_objects/django/api/photo_change_request.py,sha256=v94RA7SUM60tC9mIZdz8HppbNKfHWeTFNPr_BPw3pys,3075
|
|
22
|
-
photo_objects/django/api/utils.py,sha256=
|
|
22
|
+
photo_objects/django/api/utils.py,sha256=73yT8s5N7MtgHbIs7us7GQX3t5vOue_2-wHiUGyD81s,5394
|
|
23
23
|
photo_objects/django/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
24
|
photo_objects/django/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
25
25
|
photo_objects/django/management/commands/clean-scaled-photos.py,sha256=KJY6phgTCxcmbMUsUfCRQjatvCmKyFninM8zT-tB3Kc,2008
|
|
@@ -43,24 +43,24 @@ photo_objects/django/tests/test_img.py,sha256=HEAWcr5fpTkzePkhoQ4YrWsDO9TvFOr7my
|
|
|
43
43
|
photo_objects/django/tests/test_og_meta.py,sha256=Kk5a9KvE88KZ60gLqXSe6rTz5YU-gdjteksYolHd-nw,1804
|
|
44
44
|
photo_objects/django/tests/test_photo.py,sha256=JWXN3fF2VtuByMKm2o5b19HnxwDr6ecRwuGzgc5RsBw,13471
|
|
45
45
|
photo_objects/django/tests/test_photo_change_requests.py,sha256=Ld5ytqxxZiEWrqfX8htJ6-5ARU7tqTYD-iUhb7EMcnU,3078
|
|
46
|
-
photo_objects/django/tests/test_utils.py,sha256=
|
|
46
|
+
photo_objects/django/tests/test_utils.py,sha256=kJKjKltbc-qj53BXc9UoQR6ABMMN_gNTQ3cUj3V41Dw,2173
|
|
47
47
|
photo_objects/django/tests/utils.py,sha256=LiObyRARkmO4arnY2gXNi_T8XxT9eSKKszENMo2UIh8,4639
|
|
48
48
|
photo_objects/django/views/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
49
|
-
photo_objects/django/views/utils.py,sha256=
|
|
49
|
+
photo_objects/django/views/utils.py,sha256=19FO5LpZFVX9i01B_RvmV7b5zhJsQk8ZDVJzTgeD7SQ,2550
|
|
50
50
|
photo_objects/django/views/api/__init__.py,sha256=GgywMJMSFmP5aoMEaYut5V666zachd5YFQIDBMr5znU,188
|
|
51
51
|
photo_objects/django/views/api/album.py,sha256=EZMOkxYzLSWr9wwXnd4yAO64JtXZq2k3FYohiNMFbGQ,1602
|
|
52
52
|
photo_objects/django/views/api/auth.py,sha256=EN_ExegzmLN-bhSzu3L9-6UE9qodPd7_ZRLilzrvc8Y,819
|
|
53
53
|
photo_objects/django/views/api/photo.py,sha256=WHSayWTi_wG6otq6Rz1IKqJ5ik5riclR3AWB15ge5RU,4613
|
|
54
54
|
photo_objects/django/views/api/utils.py,sha256=uQzKdSKHRAux5OZzqgWQr0gsK_FeweQP0cg_67OWA_Y,264
|
|
55
55
|
photo_objects/django/views/ui/__init__.py,sha256=Y3XrckZExbHpWVNwDUGLfb99_midb8-5j6Ouf_Yu_G4,128
|
|
56
|
-
photo_objects/django/views/ui/album.py,sha256=
|
|
57
|
-
photo_objects/django/views/ui/configuration.py,sha256=
|
|
58
|
-
photo_objects/django/views/ui/photo.py,sha256=
|
|
59
|
-
photo_objects/django/views/ui/photo_change_request.py,sha256=
|
|
60
|
-
photo_objects/django/views/ui/users.py,sha256=
|
|
61
|
-
photo_objects/django/views/ui/utils.py,sha256=
|
|
62
|
-
photo_objects-0.
|
|
63
|
-
photo_objects-0.
|
|
64
|
-
photo_objects-0.
|
|
65
|
-
photo_objects-0.
|
|
66
|
-
photo_objects-0.
|
|
56
|
+
photo_objects/django/views/ui/album.py,sha256=IYjhjBj9MOffUDUSTm3IMjJoz-xGfvA_LVa0Vc_aXV8,5167
|
|
57
|
+
photo_objects/django/views/ui/configuration.py,sha256=miEJTm_cRANu9Wt3SCcU-tYUwM7WLKgQm8zgApmKMxE,5464
|
|
58
|
+
photo_objects/django/views/ui/photo.py,sha256=EOu43klthhmG6ysCrw2NWb7Vcz8I3FBR6GZUFhLBLG4,6281
|
|
59
|
+
photo_objects/django/views/ui/photo_change_request.py,sha256=PGP98APOVTkTw3FTvzYn92BBshensFwA8U0w8l1vIjg,2127
|
|
60
|
+
photo_objects/django/views/ui/users.py,sha256=ABAtKwNoViYy2ht6X313BSm6wgvL302LVUNimp43gxc,649
|
|
61
|
+
photo_objects/django/views/ui/utils.py,sha256=fAEgG6cdL_u9TBLWgqQGG8zC0RX1a-9vC6C06ST7InM,823
|
|
62
|
+
photo_objects-0.10.0.dist-info/licenses/LICENSE,sha256=V3w6hTjXfP65F4r_mejveHcV5igHrblxao3-2RlfVlA,1068
|
|
63
|
+
photo_objects-0.10.0.dist-info/METADATA,sha256=NoIKg2yngg8mybPuaHUl336sipa2ftiG7JSWJWxJzOo,3616
|
|
64
|
+
photo_objects-0.10.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
65
|
+
photo_objects-0.10.0.dist-info/top_level.txt,sha256=SZeL8mhf-WMGdhRtTGFvZc3aIRBboQls9O0cFDMGdQ0,14
|
|
66
|
+
photo_objects-0.10.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|