From 516f90bf1f97afa488aff598dc2454131518aef5 Mon Sep 17 00:00:00 2001 From: Yvan Date: Tue, 4 Feb 2025 19:42:09 +0000 Subject: [PATCH] improvements to generating URIs and some template tweaks, minor tidying --- .../dev/activitypub/activitypubbot/Bot.java | 11 +++- .../activitypubbot/BotService.java | 56 ++++++++++++++++--- .../activitypubbot/RestHandler.java | 9 ++- .../src/main/resources/application.properties | 3 + .../main/resources/templates/listbots.html | 22 +++----- .../src/main/resources/templates/viewbot.html | 27 ++++++--- 6 files changed, 93 insertions(+), 35 deletions(-) diff --git a/Java/Spring/activitypubbot/src/main/java/dev/activitypub/activitypubbot/Bot.java b/Java/Spring/activitypubbot/src/main/java/dev/activitypub/activitypubbot/Bot.java index ca5b289..85b3c74 100644 --- a/Java/Spring/activitypubbot/src/main/java/dev/activitypub/activitypubbot/Bot.java +++ b/Java/Spring/activitypubbot/src/main/java/dev/activitypub/activitypubbot/Bot.java @@ -76,7 +76,15 @@ public class Bot { Bot() { } - Bot( String username, String name, String summary, Instant published, KeyPair keyPair, String type, boolean manuallyApproveFollowers, boolean indexable ) { + Bot( + String username, + String name, + String summary, + Instant published, + KeyPair keyPair, + String type, + boolean manuallyApproveFollowers, + boolean indexable ) { this.username = username; this.name = name; this.summary = summary; @@ -86,5 +94,6 @@ public class Bot { this.manuallyApproveFollowers = manuallyApproveFollowers; this.indexable = indexable; } + } diff --git a/Java/Spring/activitypubbot/src/main/java/dev/activitypub/activitypubbot/BotService.java b/Java/Spring/activitypubbot/src/main/java/dev/activitypub/activitypubbot/BotService.java index cfc9cea..305553d 100644 --- a/Java/Spring/activitypubbot/src/main/java/dev/activitypub/activitypubbot/BotService.java +++ b/Java/Spring/activitypubbot/src/main/java/dev/activitypub/activitypubbot/BotService.java @@ -4,6 +4,7 @@ import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.util.UriComponentsBuilder; import java.util.List; /** @@ -35,36 +36,73 @@ public class BotService { } - // whilst the URI structure of the below are up to the implementor we're using Mastodon as a reference + // whilst the URI structure of the below are up to the implementer we're using Mastodon as a reference - // TODO: perhaps these could just be templated elsewhere... or part of a separat JSON generator + // TODO: I've fiddled around loads with where to house/generate the values + // from the calls below, they have ended up here mainly as this is where it + // is cleanest to access the configuration properties. + // + // Opinion in material I've read seems very firm that knowledge of + // "configuration" should not exist at Entity level so I have not made them + // members of the Bot class. I've toyed with the idea of them simply all + // being kept as database values and generated on creation... and in some + // ways that is simply cleaner and thus still has an appeal to it. I just + // also feel uncomfortable about having a load of "derived data" in the + // database, even though there is also a efficiency argument. Perhaps the + // combination of both efficiency + design-readability should win it. (In + // which case this code could well just stay here to be used at creation.) /** - * Generate the users URI + * Generate the webfinger subject */ - private String getUsersURI() { - return props.getScheme() + "://" + props.getDomain() + "/users/"; + public String getWebfingerSubject(Bot bot) { + return "acct:" + bot.getUsername() + "@" + props.getDomain(); } /** - * The"id" of a bot (user/actor) is a URI combining domain and username: https:///users/ + * Generate the webfinger subject + */ + public String getHandle(Bot bot) { + return "@" + bot.getUsername() + "@" + props.getDomain(); + } + + /** + * Generate the base users URI + */ + private UriComponentsBuilder getUsersURI() { + return UriComponentsBuilder.newInstance() + .scheme(props.getScheme()) + .host(props.getDomain()) + .pathSegment("users"); + } + + /** + * The "id" of a bot (user/actor) is a URI combining domain and username: https:///users/ */ public String getId(Bot bot) { - return getUsersURI() + bot.getUsername(); + return getUsersURI() + .pathSegment(bot.getUsername()) + .toUriString(); } /** * The "inbox" of a user is a URI of the form: https:///users//inbox */ public String getInbox(Bot bot) { - return getUsersURI() + bot.getUsername() + "/inbox"; + return getUsersURI() + .pathSegment(bot.getUsername()) + .pathSegment("inbox") + .toUriString(); } /** * The "outbox" of a user is a URI of the form: https:///users//outbox */ public String getOutbox(Bot bot) { - return getUsersURI() + bot.getUsername() + "/outbox"; + return getUsersURI() + .pathSegment(bot.getUsername()) + .pathSegment("outbox") + .toUriString(); } public Bot save(Bot bot) { diff --git a/Java/Spring/activitypubbot/src/main/java/dev/activitypub/activitypubbot/RestHandler.java b/Java/Spring/activitypubbot/src/main/java/dev/activitypub/activitypubbot/RestHandler.java index c688877..dc2deae 100644 --- a/Java/Spring/activitypubbot/src/main/java/dev/activitypub/activitypubbot/RestHandler.java +++ b/Java/Spring/activitypubbot/src/main/java/dev/activitypub/activitypubbot/RestHandler.java @@ -65,14 +65,17 @@ public class RestHandler { //return new ResponseEntity<>("These are not the droids you are looking for.", HttpStatus.NOT_FOUND); } - // TODO: So here's a whole other way of generating custom JSON as compared to the BotAPActorJSONSerializer approach + // TODO: So here's a whole other way of generating custom JSON as + // compared to the BotAPActorJSONSerializer approach, should perhaps + // settle on one style of doing it (if we're going to do it either way + // in the end.) Map response = Map.of( - "subject", bot.getUsername() + "@springbot.seth.id.au", + "subject", botServ.getWebfingerSubject( bot ), "links", List.of( Map.of( "rel", "self", "type", "application/activity+json", - "href", "https://springbot.seth.id.au/users/" + bot.getUsername() + "href", botServ.getId( bot ) ) ) ); diff --git a/Java/Spring/activitypubbot/src/main/resources/application.properties b/Java/Spring/activitypubbot/src/main/resources/application.properties index 205e641..161a5fe 100644 --- a/Java/Spring/activitypubbot/src/main/resources/application.properties +++ b/Java/Spring/activitypubbot/src/main/resources/application.properties @@ -6,6 +6,9 @@ logging.file.name=logs/springbot.log logging.file.path=logs spring.output.ansi.enabled=ALWAYS logging.level.org.springframework.web.filter.CommonsRequestLoggingFilter=DEBUG +server.tomcat.basedir=logs +server.tomcat.accesslog.enabled=true +server.tomcat.accesslog.pattern=%t %a "%r" %s (%D ms) spring.mvc.view.prefix: /WEB-INF/views/ spring.mvc.view.suffix: .jsp diff --git a/Java/Spring/activitypubbot/src/main/resources/templates/listbots.html b/Java/Spring/activitypubbot/src/main/resources/templates/listbots.html index fba2e1a..055282a 100644 --- a/Java/Spring/activitypubbot/src/main/resources/templates/listbots.html +++ b/Java/Spring/activitypubbot/src/main/resources/templates/listbots.html @@ -3,25 +3,21 @@ List Bot - -
+

Pick-a-Bot!

-
    -
  • No Bots!
  • -
- - Bot: - [[${bot.username}]] -
+ +

No Bots!

+ + [[${@botService.getHandle(bot)}]]
+
+

HOME
diff --git a/Java/Spring/activitypubbot/src/main/resources/templates/viewbot.html b/Java/Spring/activitypubbot/src/main/resources/templates/viewbot.html index 595ce4b..b86b4b1 100644 --- a/Java/Spring/activitypubbot/src/main/resources/templates/viewbot.html +++ b/Java/Spring/activitypubbot/src/main/resources/templates/viewbot.html @@ -4,24 +4,33 @@ View Bot -
+

Bot:

- Username:
- Id:
- Display Name:
- Description:
- Published:
- Type:
- Public Key:

+ Username:
+ Id:
+ Display Name:
+ Description:
+ Published:
+ Type:
+ Public Key: +

+    

HOME | Bot List