Skip to content

Commit

Permalink
Improve handling of deleted users in templates
Browse files Browse the repository at this point in the history
  • Loading branch information
grishka committed Oct 28, 2023
1 parent 39ffc69 commit 877f14d
Show file tree
Hide file tree
Showing 54 changed files with 216 additions and 121 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ public class DeletePersonHandler extends ActivityTypeHandler<ForeignUser, Delete
public void handle(ActivityHandlerContext context, ForeignUser actor, Delete activity, ForeignUser object) throws SQLException{
if(actor.id!=object.id)
throw new BadRequestException("User can only delete themselves");
// not implemented yet
context.appContext.getUsersController().deleteForeignUser(actor);
}
}
8 changes: 8 additions & 0 deletions src/main/java/smithereen/controllers/UsersController.java
Original file line number Diff line number Diff line change
Expand Up @@ -276,4 +276,12 @@ public Map<Integer, User> getUsers(Collection<Integer> ids){
throw new InternalServerErrorException(x);
}
}

public void deleteForeignUser(ForeignUser user){
try{
UserStorage.deleteUser(user);
}catch(SQLException x){
throw new InternalServerErrorException(x);
}
}
}
8 changes: 8 additions & 0 deletions src/main/java/smithereen/storage/UserStorage.java
Original file line number Diff line number Diff line change
Expand Up @@ -1160,4 +1160,12 @@ public static int getCountOfFriendsOfFriendsWithDomain(int userID, String domain
return DatabaseUtils.oneFieldToInt(stmt.executeQuery());
}
}

public static void deleteUser(User user) throws SQLException{
new SQLQueryBuilder()
.deleteFrom("users")
.where("id=?", user.id)
.executeNoResult();
removeFromCache(user);
}
}
39 changes: 39 additions & 0 deletions src/main/java/smithereen/templates/NameFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package smithereen.templates;

import java.util.List;
import java.util.Map;

import io.pebbletemplates.pebble.error.PebbleException;
import io.pebbletemplates.pebble.extension.Filter;
import io.pebbletemplates.pebble.template.EvaluationContext;
import io.pebbletemplates.pebble.template.PebbleTemplate;
import smithereen.model.Group;
import smithereen.model.User;

public class NameFilter implements Filter{
@Override
public Object apply(Object input, Map<String, Object> args, PebbleTemplate self, EvaluationContext context, int lineNumber) throws PebbleException{
if(input instanceof User user){
String format=(String) args.getOrDefault("format", "full");
return switch(format){
case "first" -> user.firstName;
case "last" -> user.lastName;
case "middle" -> user.middleName;
case "maiden" -> user.maidenName;
case "full" -> user.getFullName();
case "complete" -> user.getCompleteName();
case "firstAndGender" -> user.getFirstAndGender();
case "fullAndGender" -> user.getFirstLastAndGender();
default -> throw new IllegalStateException("Unexpected value: "+format);
};
}else if(input instanceof Group group){
return group.name;
}
return "DELETED";
}

@Override
public List<String> getArgumentNames(){
return List.of("format");
}
}
41 changes: 41 additions & 0 deletions src/main/java/smithereen/templates/ProfileUrlFunction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package smithereen.templates;

import java.util.List;
import java.util.Map;

import io.pebbletemplates.pebble.extension.Function;
import io.pebbletemplates.pebble.template.EvaluationContext;
import io.pebbletemplates.pebble.template.PebbleTemplate;
import smithereen.model.Group;
import smithereen.model.User;

public class ProfileUrlFunction implements Function{
@Override
public Object execute(Map<String, Object> args, PebbleTemplate self, EvaluationContext context, int lineNumber){
int id=(Integer)args.get("id");
if(id>0){
Map<Integer, User> users=(Map<Integer, User>) context.getVariable("users");
if(users==null)
return "/id"+id;
User user=users.get(id);
if(user==null)
return "/id"+id;
return user.getProfileURL();
}else if(id<0){
id=-id;
Map<Integer, Group> groups=(Map<Integer, Group>) context.getVariable("groups");
if(groups==null)
return "/club"+id;
Group group=groups.get(id);
if(group==null)
return "/club"+id;
return group.getProfileURL();
}
return null;
}

@Override
public List<String> getArgumentNames(){
return List.of("id");
}
}
44 changes: 23 additions & 21 deletions src/main/java/smithereen/templates/SmithereenExtension.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,33 @@
public class SmithereenExtension extends AbstractExtension{
@Override
public Map<String, Function> getFunctions(){
return Map.of(
"L", new LangFunction(),
"LD", new LangDateFunction(),
"renderAttachments", new RenderAttachmentsFunction(),
"json", new JsonFunction(),
"formatTime", new FormatTimeFunction(),
"getTime", new InstantToTimeFunction(),
"getDate", new InstantToDateFunction(),
"describeAttachments", new DescribeAttachmentsFunction(),
"addQueryParams", new AddQueryParamsFunction(),
"randomString", new RandomStringFunction()
);
Map<String, Function> f=new HashMap<>();
f.put("L", new LangFunction());
f.put("LD", new LangDateFunction());
f.put("renderAttachments", new RenderAttachmentsFunction());
f.put("json", new JsonFunction());
f.put("formatTime", new FormatTimeFunction());
f.put("getTime", new InstantToTimeFunction());
f.put("getDate", new InstantToDateFunction());
f.put("describeAttachments", new DescribeAttachmentsFunction());
f.put("addQueryParams", new AddQueryParamsFunction());
f.put("randomString", new RandomStringFunction());
f.put("profileURL", new ProfileUrlFunction());
return f;
}

@Override
public Map<String, Filter> getFilters(){
return Map.of(
"pictureForAvatar", new PictureForAvatarFilter(),
"pictureForPhoto", new PictureForPhotoFilter(),
"postprocessHTML", new PostprocessHTMLFilter(),
"forceEscape", new ForceEscapeFilter(),
"nl2br", new Nl2brFilter(),
"truncateText", new TruncateTextFilter(),
"stripHTML", new StripHTMLFilter()
);
Map<String, Filter> f=new HashMap<>();
f.put("pictureForAvatar", new PictureForAvatarFilter());
f.put("pictureForPhoto", new PictureForPhotoFilter());
f.put("postprocessHTML", new PostprocessHTMLFilter());
f.put("forceEscape", new ForceEscapeFilter());
f.put("nl2br", new Nl2brFilter());
f.put("truncateText", new TruncateTextFilter());
f.put("stripHTML", new StripHTMLFilter());
f.put("name", new NameFilter());
return f;
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/common/actor_list.twig
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<a href="{{ actor.actor.profileURL }}">{{ actor.actor | pictureForAvatar('s') }}</a>
</td>
<td class="info" valign="middle">
<b><a href="{{ actor.actor.profileURL }}">{{ actor.actor.type=="Person" ? actor.actor.completeName : actor.actor.name }}</a></b>
<b><a href="{{ actor.actor.profileURL }}">{{ actor.actor.type=="Person" ? actor.actor | name('complete') : actor.actor.name }}</a></b>
{% if actor.description is not empty %}
<div class="subtitle">{{ actor.description }}</div>
{% endif %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
{{ L('server_restrictions_none') }}
{% else %}
<div>{{ L('server_restrictions_suspended') }}</div>
<div class="marginBefore"><b><a href="{{ users[server.restriction.moderatorId].profileURL }}">{{ users[server.restriction.moderatorId].fullName }}</a> {{ LD(server.restriction.createdAt) }}</b>{% if server.restriction.privateComment is not null %}: {{ server.restriction.privateComment }}{% endif %}</div>
<div class="marginBefore"><b><a href="{{ profileURL(server.restriction.moderatorId) }}">{{ users[server.restriction.moderatorId] | name('full') }}</a> {{ LD(server.restriction.createdAt) }}</b>{% if server.restriction.privateComment is not null %}: {{ server.restriction.privateComment }}{% endif %}</div>
{% endif %}
</div>
<div class="marginBefore">
Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/templates/common/admin_users.twig
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
{% for acc in items %}
<tr>
<td>{{acc.id}} ({{acc.user.id}})</td>
<td class="ellipsize"><a href="{{acc.user.url}}"><span class="tinyInlineAva">{{acc.user | pictureForAvatar('s', 32)}}</span>{{acc.user.fullName}}</a></td>
<td class="ellipsize">{%if acc.invitedBy is not null%}<a href="{{acc.invitedBy.url}}"><span class="tinyInlineAva">{{acc.invitedBy | pictureForAvatar('s', 32)}}</span>{{acc.invitedBy.fullName}}</a>{%else%}&mdash;{%endif%}</td>
<td class="ellipsize"><a href="{{acc.user.url}}"><span class="tinyInlineAva">{{acc.user | pictureForAvatar('s', 32)}}</span>{{ acc.user | name('full') }}</a></td>
<td class="ellipsize">{%if acc.invitedBy is not null%}<a href="{{acc.invitedBy.url}}"><span class="tinyInlineAva">{{acc.invitedBy | pictureForAvatar('s', 32)}}</span>{{ acc.invitedBy | name('full') }}</a>{%else%}&mdash;{%endif%}</td>
<td align="center">{{LD(acc.createdAt)}}</td>
<td>
{% if acc.user.id!=currentUser.id and userPermissions.serverAccessLevel.ordinal>=3 %}
Expand Down
30 changes: 15 additions & 15 deletions src/main/resources/templates/common/feed_row.twig
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<div class="feedIcon feedIconStatus"></div>
<div class="feedRowTime">{{ formatTime(entry.time) }}</div>
<div class="feedRowContent">
{{ L(posts[entry.objectID].post.replyLevel==0 ? 'feed_retoot' : 'feed_retoot_comment', {'gender': author.gender, 'author': author.fullName}, {'author': {'href': author.profileURL} }) -}}
{{ L(posts[entry.objectID].post.replyLevel==0 ? 'feed_retoot' : 'feed_retoot_comment', {'gender': author.gender, 'author': author | name('full')}, {'author': {'href': profileURL(entry.authorID)} }) -}}
</div>
{%include "wall_post" with {'post': posts[entry.objectID]}%}
</div>
Expand All @@ -28,32 +28,32 @@
<div class="feedIcon feedIcon{{ icon }}"></div>
<div class="feedRowTime">{{ formatTime(entry.time) }}</div>
<div class="feedRowContent">
{{ L("feed_#{langKey}", {'author': author.completeName, 'gender': author.gender, 'count': entry.childEntries | length}, {'author': {'href': author.profileURL} }) }}
{{ L("feed_#{langKey}", {'author': author | name("complete"), 'gender': author.gender, 'count': entry.childEntries | length}, {'author': {'href': profileURL(entry.authorID)} }) }}
<div class="feedRowUsers">
{% for ce in entry.mostRecentEntries %}
{% if ce.type=="ADD_FRIEND" %}
<div class="feedRowUser">
{% set friend=users[ce.objectID] %}
<a href="{{ friend.profileURL }}">
{{ friend | pictureForAvatar('s') }}
<div class="feedRowUserName">{{ friend.firstName }}</div>
<div class="feedRowUserName">{{ friend.lastName }}</div>
<div class="feedRowUserName">{{ friend | name("first") }}</div>
<div class="feedRowUserName">{{ friend | name("last") }}</div>
</a>
</div>
{% elseif ce.type=="JOIN_GROUP" %}
<div class="feedRowUser">
{% set group=groups[ce.objectID] %}
<a href="{{ group.profileURL }}">
<a href="{{ profileURL(-ce.objectID) }}">
{{ group | pictureForAvatar('s') }}
<div class="feedRowUserName">{{ group.name }}</div>
<div class="feedRowUserName">{{ group | name }}</div>
</a>
</div>
{% elseif ce.type=="JOIN_EVENT" %}
<div class="feedRowUser">
{% set event=groups[ce.objectID] %}
<a href="{{ event.profileURL }}">
<a href="{{ profileURL(-ce.objectID) }}">
{{ event | pictureForAvatar('s') }}
<div class="feedRowUserName">{{ event.name }}</div>
<div class="feedRowUserName">{{ event | name }}</div>
</a>
</div>
{% endif %}
Expand All @@ -66,26 +66,26 @@
{% set friend=users[entry.objectID] %}
{% set icon="Add" %}
{% set langKey="added_friend" %}
{% set targetHref=friend.profileURL %}
{% set targetName=L('feed_added_friend_name', {'name': friend.firstLastAndGender}) %}
{% set targetHref=profileURL(entry.objectID) %}
{% set targetName=L('feed_added_friend_name', {'name': friend | name('fullAndGender')}) %}
{% elseif entry.type=="JOIN_GROUP" or entry.type=="CREATE_GROUP" %}
{% set group=groups[entry.objectID] %}
{% set icon="Group" %}
{% set langKey=(entry.type=="CREATE_GROUP" ? "created_group" : "joined_group") %}
{% set targetHref=group.profileURL %}
{% set targetName=group.name %}
{% set targetHref=profileURL(-entry.objectID) %}
{% set targetName=group | name %}
{% elseif entry.type=="JOIN_EVENT" or entry.type=="CREATE_EVENT" %}
{% set event=groups[entry.objectID] %}
{% set icon="Event" %}
{% set langKey=(entry.type=="CREATE_EVENT" ? "created_event" : "joined_event") %}
{% set targetHref=event.profileURL %}
{% set targetName=event.name %}
{% set targetHref=profileURL(-entry.objectID) %}
{% set targetName=event | name %}
{% endif %}
<div class="feedRow">
<div class="feedIcon feedIcon{{ icon }}"></div>
<div class="feedRowTime">{{ formatTime(entry.time) }}</div>
<div class="feedRowContent">
{{ L("feed_#{langKey}", {'author': author.completeName, 'target': targetName, 'gender': author.gender}, {'author': {'href': author.profileURL}, 'target': {'href': targetHref} }) }}
{{ L("feed_#{langKey}", {'author': author | name('complete'), 'target': targetName, 'gender': author.gender}, {'author': {'href': profileURL(entry.authorID)}, 'target': {'href': targetHref} }) }}
</div>
</div>
{%else%}
Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/templates/common/group_edit_blocking.twig
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
<colgroup><col width="*"/><col width="100"/></colgroup>
{% for user in blockedUsers %}
<tr>
<td><a href="{{ user.profileURL }}"><span class="tinyInlineAva">{{user | pictureForAvatar('s', 32)}}</span>{{ user.fullName }}</a></td>
<td><a href="{{ user.profileURL }}"><span class="tinyInlineAva">{{user | pictureForAvatar('s', 32)}}</span>{{ user | name('complete') }}</a></td>
<td align="right">
<a href="/groups/{{ group.id }}/confirmUnblockUser?id={{ user.id }}" data-confirm-action="/groups/{{ group.id }}/unblockUser?id={{ user.id }}" data-confirm-title="{{ L('unblock') }}" data-confirm-message="{{ L('confirm_unblock_user_X', {'name': user.firstLastAndGender}) | forceEscape }}">{{ L('unblock') }}</a>
<a href="/groups/{{ group.id }}/confirmUnblockUser?id={{ user.id }}" data-confirm-action="/groups/{{ group.id }}/unblockUser?id={{ user.id }}" data-confirm-title="{{ L('unblock') }}" data-confirm-message="{{ L('confirm_unblock_user_X', {'name': user | name('fullAndGender')}) | forceEscape }}">{{ L('unblock') }}</a>
</td>
</tr>
{% else %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
{% for user in users %}
<a class="qsearchResult" href="{{ user.profileURL }}">
{{ user | pictureForAvatar('s', avaSize) }}
<div class="qsearchName ellipsize">{{ user.fullName }}</div>
<div class="qsearchName ellipsize">{{ user | name('full') }}</div>
</a>
{% endfor %}
{% endif %}
Expand Down
10 changes: 5 additions & 5 deletions src/main/resources/templates/common/report_list.twig
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
{% if report.targetType=='USER' %}
{% set user=users[report.targetID] %}
<div class="flL smallMarginRight"><a href="{{ user.profileURL }}">{{ user | pictureForAvatar('s') }}</a></div>
<div class="ellipsize"><a href="{{ user.profileURL }}"><b>{{ user.completeName }}</b></a></div>
<div class="ellipsize"><a href="{{ user.profileURL }}"><b>{{ user | name('complete') }}</b></a></div>
<div class="grayText ellipsize">@{{ user.fullUsername }}</div>
{% elseif report.targetType=='GROUP' %}
{% set group=groups[report.targetID] %}
Expand All @@ -30,7 +30,7 @@
<div class="ellipsize">
<span class="grayText">{{ L('report_from') }}:</span>
{% if report.reporterID!=0 %}
<a href="{{ users[report.reporterID].profileURL }}">{{ users[report.reporterID].completeName }}</a>
<a href="{{ profileURL(report.reporterID) }}">{{ users[report.reporterID] | name('complete') }}</a>
{% else %}
<i>{{ L('report_sender_anonymous') }}</i>
{% endif %}
Expand Down Expand Up @@ -59,8 +59,8 @@
{% set post=posts[report.contentID] %}
{% if post is not null %}
<div class="grayText">{{ L(post.replyLevel>0 ? 'content_type_comment' : 'content_type_post') }}: <a href="/posts/{{ post.id }}?report={{ report.id }}" target="_blank">{{ LD(post.createdAt) }}</a></div>
<b>{{ users[post.authorID].fullName }}</b>
{% if post.authorID!=post.ownerID %}&raquo; <b><a href="{{ users[post.ownerID].profileURL }}">{{ users[post.ownerID].name }}</a></b>{% endif %}
<b>{{ users[post.authorID] | name('full') }}</b>
{% if post.authorID!=post.ownerID %}&raquo; <b><a href="{{ profileURL(post.ownerID) }}">{{ (post.ownerID>0 ? users[post.ownerID] : groups[-post.ownerID]) | name }}</a></b>{% endif %}
{% if post.text is not empty %}{{ post.text | stripHTML | truncateText }}{% endif %}
{% if post.attachments is not empty %}
<div>[ {{ describeAttachments(post.processedAttachments) }} ]</div>
Expand All @@ -77,7 +77,7 @@
{% set msg=messages[report.contentID] %}
{% if msg is not null %}
<div class="grayText">{{ L('content_type_message') }}: {{ LD(msg.createdAt) }}</div>
<b>{{ users[msg.senderID].fullName }}</b>
<b>{{ users[msg.senderID] | name }}</b>
{% if msg.text is not empty %}{{ msg.text | stripHTML | truncateText }}{% endif %}
{% if msg.attachments is not empty %}
<div>[ {{ describeAttachments(msg.attachments) }} ]</div>
Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/templates/common/settings_blocking.twig
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
<colgroup><col width="*"/><col width="100"/></colgroup>
{% for user in blockedUsers %}
<tr>
<td><a href="{{ user.profileURL }}"><span class="tinyInlineAva">{{user | pictureForAvatar('s', 32)}}</span>{{ user.fullName }}</a></td>
<td><a href="{{ user.profileURL }}"><span class="tinyInlineAva">{{user | pictureForAvatar('s', 32)}}</span>{{ user | name }}</a></td>
<td align="right">
<a href="/users/{{ user.id }}/confirmUnblock" data-confirm-action="/users/{{ user.id }}/unblock" data-confirm-title="{{ L('unblock') }}" data-confirm-message="{{ L('confirm_unblock_user_X', {'name': user.firstLastAndGender}) | forceEscape }}">{{ L('unblock') }}</a>
<a href="/users/{{ user.id }}/confirmUnblock" data-confirm-action="/users/{{ user.id }}/unblock" data-confirm-title="{{ L('unblock') }}" data-confirm-message="{{ L('confirm_unblock_user_X', {'name': user | name('fullAndGender')}) | forceEscape }}">{{ L('unblock') }}</a>
</td>
</tr>
{% else %}
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/common/wall_tabbar.twig
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
{% if tab=="single" %}
<a href="#" class="selected">{{ L('wall_post_title') }}</a>
{% elseif tab=="wall2wall" %}
<a href="#" class="selected">{{ L('wall_X_and_Y', {'name1': owner.firstName, 'name2': otherUser.firstName}) }}</a>
<a href="#" class="selected">{{ L('wall_X_and_Y', {'name1': owner | firstName, 'name2': otherUser | firstName}) }}</a>
{% endif %}
<span class="aux"><a href="{{ owner.profileURL }}">
{% if isGroup %}
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/desktop/about_server.twig
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<tr class="oneMemberRow">
<td valign="top"><a href="{{ admin.profileURL }}">{{ admin | pictureForAvatar('s', 40) }}</a></td>
<td class="nameAndInfo">
<div><a href="{{ admin.profileURL }}">{{ admin.fullName }}</a></div>
<div><a href="{{ admin.profileURL }}">{{ admin | name }}</a></div>
</td>
</tr>
{% endfor %}
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/templates/desktop/events_calendar.twig
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<td class="info">
<div class="infoInner">
<div class="grayText">{{ L('name') }}:</div>
<div><a href="{{ friend.profileURL }}">{{ friend.completeName }}</a></div>
<div><a href="{{ friend.profileURL }}">{{ friend | name('complete') }}</a></div>
<div class="grayText">{{ L('birthday') }}:</div>
<div>{{ userDays[friend.id] }}</div>
<div class="grayText">{{ L('birthday_turns') }}:</div>
Expand Down
4 changes: 2 additions & 2 deletions src/main/resources/templates/desktop/friend_requests.twig
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<td class="info" valign="top">
<div class="infoInner">
<div class="grayText">{{ L('name') }}:</div>
<div><a href="{{ req.from.profileURL }}">{{ req.from.completeName }}</a></div>
<div><a href="{{ req.from.profileURL }}">{{ req.from | name('complete') }}</a></div>
{% if req.from.domain is not empty %}
<div class="grayText">{{ L('server') }}:</div>
<div>{{ req.from.domain }}</div>
Expand All @@ -33,7 +33,7 @@
</span>
<div class="mutualPics">
{% for friend in req.mutualFriends %}
<a href="{{ friend.profileURL }}" title="{{ friend.fullName }}">{{ friend | pictureForAvatar('s', 32) }}</a>
<a href="{{ friend.profileURL }}" title="{{ friend | name }}">{{ friend | pictureForAvatar('s', 32) }}</a>
{% endfor %}
</div>
</div>
Expand Down
Loading

0 comments on commit 877f14d

Please sign in to comment.