Skip to content

Commit 98e68ab

Browse files
committed
Removed profile_slug editing, simplified code a lot
Refs #1 (comment)
1 parent 65ee21c commit 98e68ab

File tree

2 files changed

+28
-162
lines changed

2 files changed

+28
-162
lines changed

datasette_profiles/__init__.py

+26-155
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
id text primary key,
1717
name text,
1818
title text,
19-
profile_slug text unique,
2019
email text,
2120
bio text
2221
);
@@ -44,7 +43,6 @@ async def inner():
4443

4544
async def edit_profile(request: Request, datasette):
4645
actor = request.actor
47-
# Check if the user is logged in
4846
if not actor:
4947
raise Forbidden("You must be logged in to edit your profile")
5048

@@ -57,7 +55,7 @@ async def edit_profile(request: Request, datasette):
5755
"""
5856
select
5957
profiles.id, profiles.name, profiles.title,
60-
profiles.profile_slug, profiles.email, profiles.bio,
58+
profiles.email, profiles.bio,
6159
profiles_avatars.avatar_image is not null as has_avatar
6260
from
6361
profiles
@@ -77,161 +75,35 @@ async def edit_profile(request: Request, datasette):
7775
if request.method == "POST":
7876
post_vars = await request.post_vars()
7977
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")
8580
}
8681

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-
15882
save_avatar_data = None
159-
# Handle avatar upload if present (from hidden input)
16083
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
16286
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)
16591
try:
166-
# Add padding if needed
167-
missing_padding = len(base64_data) % 4
168-
if missing_padding:
169-
base64_data += "=" * (4 - missing_padding)
17092
save_avatar_data = base64.b64decode(base64_data)
17193
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:
20196
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
22698
)
99+
return Response.redirect(request.path)
227100

228101
# Handle avatar deletion if requested (and no new avatar provided)
229102
if post_vars.get("delete_avatar") and not save_avatar_data:
230103
await internal_db.execute_write(
231104
"delete from profiles_avatars where profile_id = :profile_id",
232105
{"profile_id": actor_id},
233106
)
234-
# Save new avatar data if provided (this overwrites existing)
235107
elif save_avatar_data:
236108
await internal_db.execute_write(
237109
"""
@@ -248,12 +120,12 @@ async def edit_profile(request: Request, datasette):
248120
await internal_db.execute_write(
249121
"""
250122
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
257129
""",
258130
{"id": actor_id, **formdata},
259131
)
@@ -262,9 +134,9 @@ async def edit_profile(request: Request, datasette):
262134
await internal_db.execute_write(
263135
"""
264136
insert into profiles
265-
(id, name, title, profile_slug, email, bio)
137+
(id, name, title, email, bio)
266138
values
267-
(:id, :name, :title, :profile_slug, :email, :bio)
139+
(:id, :name, :title, :email, :bio)
268140
""",
269141
{"id": actor_id, **formdata},
270142
)
@@ -294,6 +166,7 @@ async def edit_profile(request: Request, datasette):
294166
"edit_profile.html",
295167
{
296168
"profile": profile_data,
169+
"profile_url": datasette.urls.path(f"/~{quote(actor_id)}"),
297170
"avatar_url": avatar_url,
298171
"message": message,
299172
},
@@ -308,7 +181,6 @@ def _default_profile_data(actor):
308181
"id": actor["id"],
309182
"name": actor.get("name") or actor.get("username") or actor["id"],
310183
"title": "",
311-
"profile_slug": None,
312184
"email": actor.get("email") or "",
313185
"bio": "",
314186
"has_avatar": False,
@@ -329,11 +201,11 @@ async def view_profile(request: Request, datasette):
329201
await internal_db.execute(
330202
"""
331203
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,
333205
pa.avatar_image is not null as has_avatar
334206
from profiles p
335207
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
337209
""",
338210
{"key": profile_key},
339211
)
@@ -370,7 +242,7 @@ async def list_profiles(request: Request, datasette):
370242
await internal_db.execute(
371243
"""
372244
select
373-
p.id, p.name, p.title, p.profile_slug,
245+
p.id, p.name, p.title,
374246
pa.avatar_image is not null as has_avatar
375247
from profiles p
376248
left join profiles_avatars pa on p.id = pa.profile_id
@@ -383,8 +255,7 @@ async def list_profiles(request: Request, datasette):
383255
for row in profiles_rows:
384256
profile_dict = dict(row)
385257
# 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'])}")
388259
if profile_dict["has_avatar"]:
389260
profile_dict["avatar_url"] = _get_avatar_url(datasette, profile_dict["id"])
390261
else:

datasette_profiles/templates/edit_profile.html

+2-7
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103

104104
{% block content %}
105105
<h1>Edit your profile</h1>
106+
<p><a href="{{ profile_url }}">View your profile</a></p>
106107

107108
<form action="{{ request.path }}" method="post">
108109
<input type="hidden" name="csrftoken" value="{{ csrftoken() }}">
@@ -116,13 +117,7 @@ <h1>Edit your profile</h1>
116117
<label for="title">Job title / one-line bio</label>
117118
<input type="text" id="title" name="title" value="{{ profile.title }}" class="form-control">
118119
</div>
119-
120-
<div class="form-group">
121-
<label for="profile_slug">Custom profile slug (optional)</label>
122-
<input type="text" id="profile_slug" name="profile_slug" value="{{ profile.profile_slug or '' }}" class="form-control">
123-
<p class="help-text">Use only letters, numbers, hyphens, and underscores</p>
124-
</div>
125-
120+
126121
<div class="form-group">
127122
<label for="email">Email (visible to other members)</label>
128123
<input type="email" id="email" name="email" value="{{ profile.email }}" class="form-control">

0 commit comments

Comments
 (0)