16
16
id text primary key,
17
17
name text,
18
18
title text,
19
- profile_slug text unique,
20
19
email text,
21
20
bio text
22
21
);
@@ -44,7 +43,6 @@ async def inner():
44
43
45
44
async def edit_profile (request : Request , datasette ):
46
45
actor = request .actor
47
- # Check if the user is logged in
48
46
if not actor :
49
47
raise Forbidden ("You must be logged in to edit your profile" )
50
48
@@ -57,7 +55,7 @@ async def edit_profile(request: Request, datasette):
57
55
"""
58
56
select
59
57
profiles.id, profiles.name, profiles.title,
60
- profiles.profile_slug, profiles. email, profiles.bio,
58
+ profiles.email, profiles.bio,
61
59
profiles_avatars.avatar_image is not null as has_avatar
62
60
from
63
61
profiles
@@ -77,161 +75,35 @@ async def edit_profile(request: Request, datasette):
77
75
if request .method == "POST" :
78
76
post_vars = await request .post_vars ()
79
77
formdata = {
80
- "name" : (post_vars .get ("name" ) or "" ).strip (),
81
- "title" : (post_vars .get ("title" ) or "" ).strip (),
82
- "profile_slug" : (post_vars .get ("profile_slug" ) or "" ).strip () or None ,
83
- "email" : (post_vars .get ("email" ) or "" ).strip (),
84
- "bio" : (post_vars .get ("bio" ) or "" ).strip (),
78
+ key : (post_vars .get (key ) or "" ).strip ()
79
+ for key in ("name" , "title" , "email" , "bio" )
85
80
}
86
81
87
- # Validate slug format if provided
88
- if formdata ["profile_slug" ] and not _is_valid_slug (formdata ["profile_slug" ]):
89
- datasette .add_message (
90
- request ,
91
- "Profile slug must contain only letters, numbers, hyphens and underscores" ,
92
- datasette .ERROR ,
93
- )
94
- # Re-fetch profile data to render form correctly after error
95
- profile_data = (
96
- dict (profile_row ) if profile_exists else _default_profile_data (actor )
97
- )
98
- avatar_url = (
99
- _get_avatar_url (datasette , actor_id )
100
- if profile_data .get ("has_avatar" )
101
- else None
102
- )
103
- return Response .html (
104
- await datasette .render_template (
105
- "edit_profile.html" ,
106
- {
107
- "profile" : profile_data ,
108
- "avatar_url" : avatar_url ,
109
- "message" : None , # Error message is already added
110
- },
111
- request = request ,
112
- )
113
- )
114
-
115
- # Check for slug uniqueness if provided and changed/new
116
- if formdata ["profile_slug" ] and (
117
- not profile_exists
118
- or formdata ["profile_slug" ] != profile_row ["profile_slug" ]
119
- ):
120
- existing = (
121
- await internal_db .execute (
122
- "select id from profiles where profile_slug = :slug and id != :id" ,
123
- {"slug" : formdata ["profile_slug" ], "id" : actor_id },
124
- )
125
- ).first ()
126
-
127
- if existing :
128
- datasette .add_message (
129
- request ,
130
- f"Profile slug '{ formdata ['profile_slug' ]} ' is already in use" ,
131
- datasette .ERROR ,
132
- )
133
- # Re-fetch profile data to render form correctly after error
134
- profile_data = (
135
- dict (profile_row )
136
- if profile_exists
137
- else _default_profile_data (actor )
138
- )
139
- avatar_url = (
140
- _get_avatar_url (datasette , actor_id )
141
- if profile_data .get ("has_avatar" )
142
- else None
143
- )
144
- # Restore submitted values to the form
145
- profile_data .update (formdata )
146
- return Response .html (
147
- await datasette .render_template (
148
- "edit_profile.html" ,
149
- {
150
- "profile" : profile_data ,
151
- "avatar_url" : avatar_url ,
152
- "message" : None , # Error message is already added
153
- },
154
- request = request ,
155
- )
156
- )
157
-
158
82
save_avatar_data = None
159
- # Handle avatar upload if present (from hidden input)
160
83
avatar_data_url = post_vars .get ("avatar_data_url" )
161
- if avatar_data_url and isinstance (avatar_data_url , str ):
84
+ if avatar_data_url :
85
+ data_url_error = None
162
86
match = DATA_URL_RE .match (avatar_data_url )
163
- if match :
164
- _image_format , base64_data = match .groups ()
87
+ if not match :
88
+ data_url_error = "Invalid data URL format"
89
+ else :
90
+ base64_data = match .group (1 )
165
91
try :
166
- # Add padding if needed
167
- missing_padding = len (base64_data ) % 4
168
- if missing_padding :
169
- base64_data += "=" * (4 - missing_padding )
170
92
save_avatar_data = base64 .b64decode (base64_data )
171
93
except (binascii .Error , ValueError ):
172
- datasette .add_message (
173
- request , "Invalid avatar image data received" , datasette .ERROR
174
- )
175
- # Re-render form on error (similar to slug error handling)
176
- profile_data = (
177
- dict (profile_row )
178
- if profile_exists
179
- else _default_profile_data (actor )
180
- )
181
- avatar_url = (
182
- _get_avatar_url (datasette , actor_id )
183
- if profile_data .get ("has_avatar" )
184
- else None
185
- )
186
- profile_data .update (formdata ) # Keep user's changes
187
- return Response .html (
188
- await datasette .render_template (
189
- "edit_profile.html" ,
190
- {
191
- "profile" : profile_data ,
192
- "avatar_url" : avatar_url ,
193
- "message" : None ,
194
- },
195
- request = request ,
196
- )
197
- )
198
- elif (
199
- avatar_data_url .strip ()
200
- ): # Only error if it's non-empty but invalid format
94
+ data_url_error = "Invalid base64 data"
95
+ if data_url_error :
201
96
datasette .add_message (
202
- request , "Invalid avatar data URL format" , datasette .ERROR
203
- )
204
- # Re-render form on error
205
- profile_data = (
206
- dict (profile_row )
207
- if profile_exists
208
- else _default_profile_data (actor )
209
- )
210
- avatar_url = (
211
- _get_avatar_url (datasette , actor_id )
212
- if profile_data .get ("has_avatar" )
213
- else None
214
- )
215
- profile_data .update (formdata ) # Keep user's changes
216
- return Response .html (
217
- await datasette .render_template (
218
- "edit_profile.html" ,
219
- {
220
- "profile" : profile_data ,
221
- "avatar_url" : avatar_url ,
222
- "message" : None ,
223
- },
224
- request = request ,
225
- )
97
+ request , "Invalid avatar image data received" , datasette .ERROR
226
98
)
99
+ return Response .redirect (request .path )
227
100
228
101
# Handle avatar deletion if requested (and no new avatar provided)
229
102
if post_vars .get ("delete_avatar" ) and not save_avatar_data :
230
103
await internal_db .execute_write (
231
104
"delete from profiles_avatars where profile_id = :profile_id" ,
232
105
{"profile_id" : actor_id },
233
106
)
234
- # Save new avatar data if provided (this overwrites existing)
235
107
elif save_avatar_data :
236
108
await internal_db .execute_write (
237
109
"""
@@ -248,12 +120,12 @@ async def edit_profile(request: Request, datasette):
248
120
await internal_db .execute_write (
249
121
"""
250
122
update profiles set
251
- name = :name,
252
- title = :title,
253
- profile_slug = :profile_slug ,
254
- email = :email,
255
- bio = :bio
256
- where id = :id
123
+ name = :name,
124
+ title = :title,
125
+ email = :email ,
126
+ bio = :bio
127
+ where
128
+ id = :id
257
129
""" ,
258
130
{"id" : actor_id , ** formdata },
259
131
)
@@ -262,9 +134,9 @@ async def edit_profile(request: Request, datasette):
262
134
await internal_db .execute_write (
263
135
"""
264
136
insert into profiles
265
- (id, name, title, profile_slug, email, bio)
137
+ (id, name, title, email, bio)
266
138
values
267
- (:id, :name, :title, :profile_slug, : email, :bio)
139
+ (:id, :name, :title, :email, :bio)
268
140
""" ,
269
141
{"id" : actor_id , ** formdata },
270
142
)
@@ -294,6 +166,7 @@ async def edit_profile(request: Request, datasette):
294
166
"edit_profile.html" ,
295
167
{
296
168
"profile" : profile_data ,
169
+ "profile_url" : datasette .urls .path (f"/~{ quote (actor_id )} " ),
297
170
"avatar_url" : avatar_url ,
298
171
"message" : message ,
299
172
},
@@ -308,7 +181,6 @@ def _default_profile_data(actor):
308
181
"id" : actor ["id" ],
309
182
"name" : actor .get ("name" ) or actor .get ("username" ) or actor ["id" ],
310
183
"title" : "" ,
311
- "profile_slug" : None ,
312
184
"email" : actor .get ("email" ) or "" ,
313
185
"bio" : "" ,
314
186
"has_avatar" : False ,
@@ -329,11 +201,11 @@ async def view_profile(request: Request, datasette):
329
201
await internal_db .execute (
330
202
"""
331
203
select
332
- p.id, p.name, p.title, p.profile_slug, p. email, p.bio,
204
+ p.id, p.name, p.title, p.email, p.bio,
333
205
pa.avatar_image is not null as has_avatar
334
206
from profiles p
335
207
left join profiles_avatars pa on p.id = pa.profile_id
336
- where p.profile_slug = :key or p. id = :key
208
+ where p.id = :key
337
209
""" ,
338
210
{"key" : profile_key },
339
211
)
@@ -370,7 +242,7 @@ async def list_profiles(request: Request, datasette):
370
242
await internal_db .execute (
371
243
"""
372
244
select
373
- p.id, p.name, p.title, p.profile_slug,
245
+ p.id, p.name, p.title,
374
246
pa.avatar_image is not null as has_avatar
375
247
from profiles p
376
248
left join profiles_avatars pa on p.id = pa.profile_id
@@ -383,8 +255,7 @@ async def list_profiles(request: Request, datasette):
383
255
for row in profiles_rows :
384
256
profile_dict = dict (row )
385
257
# Determine the correct URL for the profile view
386
- profile_key = profile_dict ["profile_slug" ] or profile_dict ["id" ]
387
- profile_dict ["view_url" ] = datasette .urls .path (f"/~{ quote (profile_key )} " )
258
+ profile_dict ["view_url" ] = datasette .urls .path (f"/~{ quote (profile_dict ['id' ])} " )
388
259
if profile_dict ["has_avatar" ]:
389
260
profile_dict ["avatar_url" ] = _get_avatar_url (datasette , profile_dict ["id" ])
390
261
else :
0 commit comments