aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2023-01-09 09:45:12 +0300
committerGravatar Vitaly Takmazov2023-01-09 09:45:12 +0300
commitf6b78c029a1e9e4f09b600131e99bbc13c65f30a (patch)
tree33511c92dd418d1eced2b4755fc16a583c135d06
parent6b08c391d27a682ffece9e9c471986160e2f94af (diff)
Mastodon API: statuses
-rw-r--r--src/main/java/com/juick/ActivityPubManager.java37
-rw-r--r--src/main/java/com/juick/www/api/Mastodon.java31
-rw-r--r--src/main/java/com/juick/www/api/activity/Profile.java10
-rw-r--r--src/main/java/com/juick/www/api/activity/helpers/ProfileUriBuilder.java9
4 files changed, 66 insertions, 21 deletions
diff --git a/src/main/java/com/juick/ActivityPubManager.java b/src/main/java/com/juick/ActivityPubManager.java
index b62be93a..e9a04197 100644
--- a/src/main/java/com/juick/ActivityPubManager.java
+++ b/src/main/java/com/juick/ActivityPubManager.java
@@ -31,6 +31,7 @@ import com.juick.service.component.NotificationListener;
import com.juick.service.component.PingEvent;
import com.juick.service.component.SystemEvent;
import com.juick.util.HttpBadRequestException;
+import com.juick.util.HttpNotFoundException;
import com.juick.util.HttpUtils;
import com.juick.util.MessageUtils;
import com.juick.util.formatters.PlainTextFormatter;
@@ -149,11 +150,11 @@ public class ActivityPubManager implements ActivityListener, NotificationListene
UriComponents uriComponents = UriComponentsBuilder.fromUriString(event.getMessageUri()).build();
List<String> segments = uriComponents.getPathSegments();
if (segments.get(0).equals("n")) {
- String[] ids = segments.get(1).split("-", 2);
- if (ids.length == 2 && Integer.parseInt(ids[1]) == 0) {
+ var message = findMessage(segments.get(1));
+ if (message != null && !MessageUtils.isReply(message)) {
// only messages
- logger.info("{} recommends {}", event.getActorUri(), Integer.valueOf(ids[0]));
- messagesService.likeMessage(Integer.parseInt(ids[0]), 0, Reaction.LIKE, event.getActorUri());
+ logger.info("{} recommends {}", event.getActorUri(), message.getMid());
+ messagesService.likeMessage(message.getMid(), 0, Reaction.LIKE, event.getActorUri());
}
}
}
@@ -163,11 +164,11 @@ public class ActivityPubManager implements ActivityListener, NotificationListene
UriComponents uriComponents = UriComponentsBuilder.fromUriString(event.getMessageUri()).build();
List<String> segments = uriComponents.getPathSegments();
if (segments.get(0).equals("n")) {
- String[] ids = segments.get(1).split("-", 2);
- if (ids.length == 2 && Integer.parseInt(ids[1]) == 0) {
+ var message = findMessage(segments.get(1));
+ if (message != null && !MessageUtils.isReply(message)) {
// only messages
- logger.info("{} stop recommending {}", event.getActorUri(), Integer.valueOf(ids[0]));
- messagesService.likeMessage(Integer.parseInt(ids[0]), 0, null, event.getActorUri());
+ logger.info("{} stop recommending {}", event.getActorUri(), message.getMid());
+ messagesService.likeMessage(message.getMid(), 0, null, event.getActorUri());
}
}
}
@@ -382,7 +383,7 @@ public class ActivityPubManager implements ActivityListener, NotificationListene
activityToFollowers(user, me, announce);
}
- public User actorToUser(URI uri) throws HttpBadRequestException, JsonProcessingException {
+ public User actorToUser(URI uri) throws HttpBadRequestException {
var context = activityPubService.get(uri);
if (context.isPresent() && context.get() instanceof Actor actor) {
User user = new User();
@@ -397,4 +398,22 @@ public class ActivityPubManager implements ActivityListener, NotificationListene
throw new HttpBadRequestException();
}
}
+ public Message findMessage(String statusId) throws HttpNotFoundException {
+ String[]ids = statusId.split("-", 2);
+ try {
+ if (ids.length == 2) {
+ return findMessage(Integer.parseInt(ids[0]), Integer.parseInt(ids[1]));
+ }
+ } catch (Exception e) {
+ logger.warn("{}: message not found, error: {}", statusId, e.getMessage());
+ }
+ throw new HttpNotFoundException();
+ }
+ public Message findMessage(int mid, int rid) throws HttpNotFoundException {
+ try {
+ return rid > 0 ? messagesService.getReply(mid, rid) : messagesService.getMessage(mid).get();
+ } catch (NoSuchElementException e) {
+ throw new HttpNotFoundException();
+ }
+ }
}
diff --git a/src/main/java/com/juick/www/api/Mastodon.java b/src/main/java/com/juick/www/api/Mastodon.java
index af1c5ef7..5982209e 100644
--- a/src/main/java/com/juick/www/api/Mastodon.java
+++ b/src/main/java/com/juick/www/api/Mastodon.java
@@ -17,6 +17,7 @@
package com.juick.www.api;
+import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
@@ -298,11 +299,11 @@ public class Mastodon {
))
: List.of();
return new Status(
- String.valueOf(message.getMid()),
+ ProfileUriBuilder.messageId(message),
message.getCreated(),
toAccount(message.getUser()),
- null,
- null,
+ message.getReplyto() > 0 ? ProfileUriBuilder.messageId(message.getMid(), message.getReplyto()) : null,
+ message.getTo().getUid() > 0 ? String.valueOf(message.getTo().getUid()) : null,
MessageUtils.isSensitive(message),
"",
"public",
@@ -314,9 +315,16 @@ public class Mastodon {
@GetMapping("/api/v1/timelines/{timeline}")
public List<Status> publicTimeline(@ModelAttribute User visitor,
@PathVariable String timeline,
- @RequestParam(value = "max_id", required = false, defaultValue = "0") int before,
+ @RequestParam(value = "max_id", required = false) String maxId,
@RequestParam(value = "only_media", required = false, defaultValue = "false") Boolean media) {
List<Integer> mids = List.of();
+ int before = 0;
+ if (maxId != null) {
+ var lastMessage = activityPubManager.findMessage(maxId);
+ if (lastMessage != null) {
+ before = lastMessage.getMid();
+ }
+ }
if (timeline.equals("public")) {
if (media) {
mids = messagesService.getPhotos(visitor.getUid(), before);
@@ -333,4 +341,19 @@ public class Mastodon {
})
.collect(Collectors.toList());
}
+ @GetMapping("/api/v1/statuses/{mid}-{rid}")
+ public Status status(@PathVariable int mid, @PathVariable int rid) {
+ return toStatus(activityPubManager.findMessage(mid, rid));
+ }
+ public record Context(@JsonInclude List<Status> ancestors, @JsonInclude List<Status> descendants) {
+
+ }
+ @GetMapping("/api/v1/statuses/{mid}-{rid}/context")
+ public Context thread(@ModelAttribute User visitor, @PathVariable int mid, @PathVariable int rid) {
+ var thread = messagesService.getReplies(visitor, mid).stream()
+ .filter(m -> m.getRid() > rid)
+ .peek(msg -> msg.getUser().setAvatar(webApp.getAvatarUrl(msg.getUser())))
+ .map(this::toStatus).toList();
+ return new Context(List.of(), thread);
+ }
}
diff --git a/src/main/java/com/juick/www/api/activity/Profile.java b/src/main/java/com/juick/www/api/activity/Profile.java
index b0a39a76..bf4bda25 100644
--- a/src/main/java/com/juick/www/api/activity/Profile.java
+++ b/src/main/java/com/juick/www/api/activity/Profile.java
@@ -256,13 +256,9 @@ public class Profile {
@GetMapping(value = "/n/{mid}-{rid}", produces = { Context.LD_JSON_MEDIA_TYPE, Context.ACTIVITY_MEDIA_TYPE,
Context.ACTIVITYSTREAMS_PROFILE_MEDIA_TYPE, MediaType.APPLICATION_JSON_VALUE })
public Context showNote(@PathVariable int mid, @PathVariable int rid) {
- try {
- Message message = rid > 0 ? messagesService.getReply(mid, rid) : messagesService.getMessage(mid).get();
- if (message != null) {
- return Context.build(activityPubManager.makeNote(message));
- }
- } catch (NoSuchElementException e) {
- throw new HttpNotFoundException();
+ var message = activityPubManager.findMessage(mid, rid);
+ if (message != null) {
+ return Context.build(activityPubManager.makeNote(message));
}
throw new HttpNotFoundException();
}
diff --git a/src/main/java/com/juick/www/api/activity/helpers/ProfileUriBuilder.java b/src/main/java/com/juick/www/api/activity/helpers/ProfileUriBuilder.java
index e10c3078..3f48502b 100644
--- a/src/main/java/com/juick/www/api/activity/helpers/ProfileUriBuilder.java
+++ b/src/main/java/com/juick/www/api/activity/helpers/ProfileUriBuilder.java
@@ -61,9 +61,16 @@ public record ProfileUriBuilder(String baseUri) {
return messageUri(msg.getMid(), msg.getRid());
}
+ public static String messageId(Message msg) {
+ return messageId(msg.getMid(), msg.getRid());
+ }
+ public static String messageId(int mid, int rid) {
+ return String.format("%d-%d", mid, rid);
+ }
+
public String messageUri(int mid, int rid) {
UriComponentsBuilder uri = UriComponentsBuilder.fromUriString(baseUri);
- uri.replacePath(String.format("/n/%d-%d", mid, rid));
+ uri.replacePath("/n/" + messageId(mid, rid));
return uri.toUriString();
}