photo-objects 0.9.0__py3-none-any.whl → 0.9.1__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/backup.py +54 -1
- photo_objects/django/management/commands/restore-backup.py +23 -1
- photo_objects/django/objsto.py +8 -0
- photo_objects/django/tests/test_utils.py +3 -0
- photo_objects/utils.py +5 -2
- {photo_objects-0.9.0.dist-info → photo_objects-0.9.1.dist-info}/METADATA +1 -1
- {photo_objects-0.9.0.dist-info → photo_objects-0.9.1.dist-info}/RECORD +10 -10
- {photo_objects-0.9.0.dist-info → photo_objects-0.9.1.dist-info}/WHEEL +0 -0
- {photo_objects-0.9.0.dist-info → photo_objects-0.9.1.dist-info}/licenses/LICENSE +0 -0
- {photo_objects-0.9.0.dist-info → photo_objects-0.9.1.dist-info}/top_level.txt +0 -0
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
from django.contrib.auth import get_user_model
|
|
2
2
|
from django.contrib.auth.models import Group, Permission
|
|
3
|
+
from django.contrib.sites.models import Site
|
|
3
4
|
from django.db import transaction
|
|
4
5
|
|
|
5
|
-
from photo_objects.django.models import Album, Backup, Photo
|
|
6
|
+
from photo_objects.django.models import Album, Backup, Photo, SiteSettings
|
|
6
7
|
from photo_objects.django.objsto import (
|
|
7
8
|
backup_data_key,
|
|
8
9
|
backup_info_key,
|
|
9
10
|
delete_backup_objects,
|
|
10
11
|
get_backup_data,
|
|
12
|
+
get_backup_object,
|
|
11
13
|
get_backup_objects,
|
|
12
14
|
put_backup_json,
|
|
13
15
|
)
|
|
@@ -55,6 +57,12 @@ def _group_dict(group: Group):
|
|
|
55
57
|
|
|
56
58
|
|
|
57
59
|
def create_backup(backup: Backup):
|
|
60
|
+
# Check if backup already exists
|
|
61
|
+
if get_backup_object(backup.id):
|
|
62
|
+
backup.status = "ready"
|
|
63
|
+
backup.save()
|
|
64
|
+
return
|
|
65
|
+
|
|
58
66
|
user_model = get_user_model()
|
|
59
67
|
|
|
60
68
|
backup.status = "pending"
|
|
@@ -99,10 +107,34 @@ def create_backup(backup: Backup):
|
|
|
99
107
|
user.username),
|
|
100
108
|
_user_dict(user))
|
|
101
109
|
|
|
110
|
+
sites = Site.objects.all()
|
|
111
|
+
for site in sites:
|
|
112
|
+
put_backup_json(
|
|
113
|
+
backup_data_key(backup.id, 'site', site.id),
|
|
114
|
+
{
|
|
115
|
+
"id": site.id,
|
|
116
|
+
"domain": site.domain,
|
|
117
|
+
"name": site.name,
|
|
118
|
+
}
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
site_settings = SiteSettings.objects.all()
|
|
122
|
+
for settings in site_settings:
|
|
123
|
+
put_backup_json(
|
|
124
|
+
backup_data_key(backup.id, 'settings', settings.site.id),
|
|
125
|
+
{
|
|
126
|
+
"site_id": settings.site.id,
|
|
127
|
+
"description": settings.description,
|
|
128
|
+
"preview_image_key": settings.preview_image.key
|
|
129
|
+
if settings.preview_image else None,
|
|
130
|
+
}
|
|
131
|
+
)
|
|
132
|
+
|
|
102
133
|
put_backup_json(backup_info_key(backup.id), backup.to_json())
|
|
103
134
|
except Exception:
|
|
104
135
|
backup.status = "create_failed"
|
|
105
136
|
backup.save()
|
|
137
|
+
raise
|
|
106
138
|
|
|
107
139
|
backup.status = "ready"
|
|
108
140
|
backup.save()
|
|
@@ -160,3 +192,24 @@ def restore_backup(backup_id: int):
|
|
|
160
192
|
if cover_photo == filename:
|
|
161
193
|
album.cover_photo = photo
|
|
162
194
|
album.save()
|
|
195
|
+
|
|
196
|
+
for i in get_backup_data(backup_id, "site"):
|
|
197
|
+
site, _ = Site.objects.get_or_create(id=i.get("id"))
|
|
198
|
+
site.domain = i.get("domain")
|
|
199
|
+
site.name = i.get("name")
|
|
200
|
+
site.save()
|
|
201
|
+
|
|
202
|
+
for i in get_backup_data(backup_id, "settings"):
|
|
203
|
+
site = Site.objects.get(id=i.get("site_id"))
|
|
204
|
+
|
|
205
|
+
preview_image = None
|
|
206
|
+
if key := i.get("preview_image_key"):
|
|
207
|
+
preview_image = Photo.objects.get(key=key)
|
|
208
|
+
|
|
209
|
+
settings = SiteSettings.objects.create(
|
|
210
|
+
site=site,
|
|
211
|
+
description=i.get("description"),
|
|
212
|
+
preview_image=preview_image
|
|
213
|
+
if i.get("preview_image_key") else None
|
|
214
|
+
)
|
|
215
|
+
settings.save()
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
# pylint: disable=invalid-name
|
|
2
|
+
from io import StringIO
|
|
3
|
+
|
|
4
|
+
from django.core.management import call_command
|
|
2
5
|
from django.core.management.base import BaseCommand
|
|
3
6
|
from django.contrib.auth import get_user_model
|
|
4
7
|
from django.contrib.auth.models import Group
|
|
8
|
+
from django.db import connection
|
|
5
9
|
|
|
6
10
|
from photo_objects.django.api.backup import get_backups, restore_backup
|
|
7
11
|
from photo_objects.django.models import Album, Photo
|
|
@@ -28,6 +32,23 @@ class DatabaseStatus:
|
|
|
28
32
|
)
|
|
29
33
|
|
|
30
34
|
|
|
35
|
+
def reset_sequences():
|
|
36
|
+
output = StringIO()
|
|
37
|
+
call_command(
|
|
38
|
+
'sqlsequencereset',
|
|
39
|
+
'photo_objects',
|
|
40
|
+
'auth',
|
|
41
|
+
'sites',
|
|
42
|
+
stdout=output,
|
|
43
|
+
no_color=True)
|
|
44
|
+
|
|
45
|
+
sql = output.getvalue()
|
|
46
|
+
with connection.cursor() as cursor:
|
|
47
|
+
cursor.execute(sql)
|
|
48
|
+
|
|
49
|
+
output.close()
|
|
50
|
+
|
|
51
|
+
|
|
31
52
|
class Command(BaseCommand):
|
|
32
53
|
help = "Restore latest backup if database is empty."
|
|
33
54
|
|
|
@@ -59,6 +80,7 @@ class Command(BaseCommand):
|
|
|
59
80
|
)
|
|
60
81
|
)
|
|
61
82
|
restore_backup(id_)
|
|
83
|
+
reset_sequences()
|
|
62
84
|
status = DatabaseStatus()
|
|
63
85
|
self.stdout.write(
|
|
64
86
|
self.style.SUCCESS(
|
|
@@ -71,4 +93,4 @@ class Command(BaseCommand):
|
|
|
71
93
|
f'Failed to restore backup: {e}'
|
|
72
94
|
)
|
|
73
95
|
)
|
|
74
|
-
|
|
96
|
+
raise
|
photo_objects/django/objsto.py
CHANGED
|
@@ -137,6 +137,14 @@ def put_backup_json(key: str, data: dict):
|
|
|
137
137
|
return _put_json(key, data, _backup_access)
|
|
138
138
|
|
|
139
139
|
|
|
140
|
+
def get_backup_object(backup_id: int):
|
|
141
|
+
client, bucket = _backup_access()
|
|
142
|
+
return json.loads(
|
|
143
|
+
client.get_object(
|
|
144
|
+
bucket,
|
|
145
|
+
backup_info_key(backup_id)).read())
|
|
146
|
+
|
|
147
|
+
|
|
140
148
|
def get_backup_objects():
|
|
141
149
|
client, bucket = _backup_access()
|
|
142
150
|
return [json.loads(i.read()) for i in _get_all(client, bucket, 'info_')]
|
|
@@ -25,6 +25,9 @@ class TestUtils(TestCase):
|
|
|
25
25
|
def test_slugify_lower(self):
|
|
26
26
|
self.assertEqual(slugify("QwErTy!", True), "qwerty-")
|
|
27
27
|
|
|
28
|
+
def test_slugify_number(self):
|
|
29
|
+
self.assertEqual(slugify(123), "123")
|
|
30
|
+
|
|
28
31
|
def test_slugify_replace_leading_underscores(self):
|
|
29
32
|
self.assertEqual(
|
|
30
33
|
slugify(
|
photo_objects/utils.py
CHANGED
|
@@ -31,9 +31,12 @@ def timestamp_str(timestamp: datetime):
|
|
|
31
31
|
return timestamp.isoformat() if timestamp else None
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
def slugify(
|
|
34
|
+
def slugify(
|
|
35
|
+
title: str | int,
|
|
36
|
+
lower=False,
|
|
37
|
+
replace_leading_underscores=False) -> str:
|
|
35
38
|
key = unicodedata.normalize(
|
|
36
|
-
'NFKD', title).encode(
|
|
39
|
+
'NFKD', str(title)).encode(
|
|
37
40
|
'ascii', 'ignore').decode('ascii')
|
|
38
41
|
if lower:
|
|
39
42
|
key = key.lower()
|
|
@@ -2,7 +2,7 @@ photo_objects/__init__.py,sha256=I1508w_ntomEqTFQgC74SurhxVXfCiDWZLRsny2f59g,60
|
|
|
2
2
|
photo_objects/config.py,sha256=0-Aeo-z-d_fxx-cjAjxSwPJZUgYaAi7NTodiErlxIXo,861
|
|
3
3
|
photo_objects/error.py,sha256=7afLYjxM0EaYioxVw_XUqHTvfSMSuQPUwwle0OVlaDY,45
|
|
4
4
|
photo_objects/img.py,sha256=2HVGS2g7rS2hnomozYL92oxrcN6zjDTHvWNr-UAqtGQ,4620
|
|
5
|
-
photo_objects/utils.py,sha256=
|
|
5
|
+
photo_objects/utils.py,sha256=M4SeHC_R4B-2LUHx_dQrY9vuzTTKjY31uwU0Vy1Hj7Q,1181
|
|
6
6
|
photo_objects/django/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
7
|
photo_objects/django/admin.py,sha256=pvyQKs2FMtKtSS2PE_NKR_jsSi7-GKz3bbsqDNgjt6w,352
|
|
8
8
|
photo_objects/django/apps.py,sha256=Apqu6o6fpoxda18NQgKupvQRvTAZxVviIK_-dUR3rck,1444
|
|
@@ -10,13 +10,13 @@ photo_objects/django/conf.py,sha256=ZpeIulEc1tpr8AO52meNKOF30Xf5osbDtDyHvQRtkx4,
|
|
|
10
10
|
photo_objects/django/context_processors.py,sha256=XacUmcYV-4NMMMNXPWrHKdvNd6lfyamisngaVerREiU,306
|
|
11
11
|
photo_objects/django/forms.py,sha256=zSSmdIYn4PEx1Nnw-tuo4h4otKj3C099lB4-vp2BRUc,6861
|
|
12
12
|
photo_objects/django/models.py,sha256=OxkkczIBg7TaFWWm4VdtbRMJOK_OQKrV29g-X2cm5BQ,7247
|
|
13
|
-
photo_objects/django/objsto.py,sha256=
|
|
13
|
+
photo_objects/django/objsto.py,sha256=NSimuKvS06dERaEPevM6v9PDxFsgz6JUhlcKmUxnnP0,6243
|
|
14
14
|
photo_objects/django/signals.py,sha256=_gb4vlZkeFNYWXxwhNreaUJoOsbIWvP8OovVLtzepaE,2161
|
|
15
15
|
photo_objects/django/urls.py,sha256=XnOSEB8YtAJamlEsjKYz6U1DfDu7HHZpAinpqdulR8k,2501
|
|
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
|
-
photo_objects/django/api/backup.py,sha256=
|
|
19
|
+
photo_objects/django/api/backup.py,sha256=_D1KMkIp7A8iPs2LxQ-MsaFcAHwCwhE7un5NRHHIvOc,6099
|
|
20
20
|
photo_objects/django/api/photo.py,sha256=-lo1g6jfBr884wy-WV2DAEPxzH9V-tFUTRtitmA6i28,4471
|
|
21
21
|
photo_objects/django/api/photo_change_request.py,sha256=v94RA7SUM60tC9mIZdz8HppbNKfHWeTFNPr_BPw3pys,3075
|
|
22
22
|
photo_objects/django/api/utils.py,sha256=8r51YgFgKPD05Zjzhstl4jlQ4JM8DtsxUyAzhjXi5Pk,5567
|
|
@@ -24,7 +24,7 @@ photo_objects/django/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm
|
|
|
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
|
|
26
26
|
photo_objects/django/management/commands/create-initial-admin-account.py,sha256=PhC7jnRxsph8rML384vKfXzYfJqMQdd8oUHxUY7JEW8,1178
|
|
27
|
-
photo_objects/django/management/commands/restore-backup.py,sha256=
|
|
27
|
+
photo_objects/django/management/commands/restore-backup.py,sha256=7Hc-6O_4hv8m66CoWbedjH20KVzURFstLPGPq6ooBuk,2607
|
|
28
28
|
photo_objects/django/migrations/0001_initial.py,sha256=BLW-EZ38sBgDhOYyprc-h_vuPpRxA11qxt4ZuYNO1Wo,2424
|
|
29
29
|
photo_objects/django/migrations/0002_created_at_updated_at.py,sha256=7OT2VvDffAkX9XKBHVY-jvzxeIl2yU0Jr1ByCNGcUfw,1039
|
|
30
30
|
photo_objects/django/migrations/0003_admin_visibility.py,sha256=PdxPOJzr-ViRBlOYUHEEGhe0hLtDysZJdMqvbjKVpEg,529
|
|
@@ -43,7 +43,7 @@ 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=0Xl0ReS2X9GsEH-jmLg8xC79hJ4nhbfULo0BOVjiykQ,2089
|
|
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
49
|
photo_objects/django/views/utils.py,sha256=AjJK5r5HmTF63E9Q4W3pKggDESuhNXUvbROpS8m70KM,1319
|
|
@@ -59,8 +59,8 @@ photo_objects/django/views/ui/photo.py,sha256=flwcET5nSChzfyAEWRTUlklTW2o64przNX
|
|
|
59
59
|
photo_objects/django/views/ui/photo_change_request.py,sha256=eaYGXFqtHj8qonDAmPyn4nrEHkL13EBD-1s8Phs0XP4,2098
|
|
60
60
|
photo_objects/django/views/ui/users.py,sha256=nb73cnzuV98QkJb0j8F2hqPgOGFIWpUFTFu6dXMeVwM,722
|
|
61
61
|
photo_objects/django/views/ui/utils.py,sha256=YV_YcUbX-zUkdFnBlezPChR6aPDhZJ9loSOHBSzF6Cc,273
|
|
62
|
-
photo_objects-0.9.
|
|
63
|
-
photo_objects-0.9.
|
|
64
|
-
photo_objects-0.9.
|
|
65
|
-
photo_objects-0.9.
|
|
66
|
-
photo_objects-0.9.
|
|
62
|
+
photo_objects-0.9.1.dist-info/licenses/LICENSE,sha256=V3w6hTjXfP65F4r_mejveHcV5igHrblxao3-2RlfVlA,1068
|
|
63
|
+
photo_objects-0.9.1.dist-info/METADATA,sha256=GoExSl5yt_qDGeEaIzeeue4bGNcIC-mcx2RgDe1i1EY,3605
|
|
64
|
+
photo_objects-0.9.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
65
|
+
photo_objects-0.9.1.dist-info/top_level.txt,sha256=SZeL8mhf-WMGdhRtTGFvZc3aIRBboQls9O0cFDMGdQ0,14
|
|
66
|
+
photo_objects-0.9.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|