Wasn't happy with that JSON templating so got rid of it rather than try and fix how it broke the HTML templating. There will be better ways to generate the required JSON.

This commit is contained in:
Yvan 2025-01-27 13:44:30 +00:00
parent 5f9f024904
commit 4f73698e2f
3 changed files with 15 additions and 186 deletions

View file

@ -9,6 +9,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.server.ResponseStatusException; import org.springframework.web.server.ResponseStatusException;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.thymeleaf.context.Context; import org.thymeleaf.context.Context;
import org.thymeleaf.spring5.SpringTemplateEngine; import org.thymeleaf.spring5.SpringTemplateEngine;
@ -22,55 +23,45 @@ public class RestHandler {
@Autowired @Autowired
private BotService botServ; private BotService botServ;
@Autowired
@Qualifier("messageTemplateEngine")
protected SpringTemplateEngine jsonTemplater;
/** /**
* Really just an alias to /user/<username> * Really just an alias to /user/<username>
*/ */
@RequestMapping(value = "/@{username}", produces = "application/activity+json") // content type based on Masto request @GetMapping(value = "/@{username}", produces = "application/activity+json") // content type based on Masto request
public String atactor(@PathVariable String username) { public ResponseEntity<String> atactor(@PathVariable String username) {
return this.actor( username ); return this.actor( username );
} }
/** /**
* Access the bot/user * Access the bot/user
*/ */
@RequestMapping(value = "/users/{username}", produces = "application/activity+json") // content type based on Masto request @GetMapping(value = "/users/{username}", produces = "application/activity+json") // content type based on Masto request
public String actor(@PathVariable String username) { public ResponseEntity<String> actor(@PathVariable String username) {
Bot bot = botServ.getBotByUsername( username ); Bot bot = botServ.getBotByUsername( username );
if( bot == null ) { if( bot == null ) {
throw new ResponseStatusException( HttpStatus.NOT_FOUND, "These are not the droids you are looking for" ); return new ResponseEntity<>("These are not the droids you are looking for.", HttpStatus.NOT_FOUND);
} }
// TODO: kludgetown... we should generate JSON programmatically rather than templates return ResponseEntity.ok(bot.toString());
final Context ctx = new Context();
ctx.setVariable("bot", bot);
final String json = jsonTemplater.process("json/actor", ctx);
return json;
} }
/** /**
* Webfinger the user... * Webfinger the user...
*/ */
@GetMapping(value = "/.well-known/webfinger", produces = "application/jrd+json") // content type based on Masto request @GetMapping(value = "/.well-known/webfinger", produces = "application/jrd+json") // content type based on Masto request
public String webfinger(@RequestParam("resource") String resource) { public ResponseEntity<String> webfinger(@RequestParam("resource") String resource) {
// resource should be of the form: acct:<username>@<domain> // resource should be of the form: acct:<username>@<domain>
// so this should be robustly checked, but for now just yoink out the username // so this should be robustly checked, but for now just yoink out the username
String username = resource.substring(resource.indexOf(":") + 1, resource.indexOf("@")); int colonPos = resource.indexOf(":");
if ( username == null) { int atPos = resource.indexOf("@");
throw new ResponseStatusException( HttpStatus.NOT_FOUND, "Malformed" ); if ( colonPos < 0 || atPos < 0 || atPos < colonPos ) {
return new ResponseEntity<>("Incorrect query format",HttpStatus.BAD_REQUEST);
} }
String username = resource.substring(colonPos + 1, atPos);
Bot bot = botServ.getBotByUsername( username ); Bot bot = botServ.getBotByUsername( username );
if( bot == null ) { if( bot == null ) {
throw new ResponseStatusException( HttpStatus.NOT_FOUND, "These are not the droids you are looking for" ); return new ResponseEntity<>("These are not the droids you are looking for.", HttpStatus.NOT_FOUND);
} }
// TODO: kludgetown... we should generate JSON programmatically rather than templates return ResponseEntity.ok(bot.toString());
final Context ctx = new Context();
ctx.setVariable("bot", bot);
final String json = jsonTemplater.process("json/webfinger", ctx);
return json;
} }
} }

View file

@ -1,99 +0,0 @@
package dev.activitypub.activitypubbot;
// Derived from: https://github.com/RAJNISH3/ThymeLeafApp/blob/master/src/main/java/com/sample/thymeleaf/ThymeleafConfiguration.java
import java.util.Collection;
import java.util.Collections;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
@Configuration
@EnableAutoConfiguration
public class ThymeleafConf {
/**
* Path to root package/directory in which the different types of message templates are found.
*/
public static final String TEMPLATES_BASE = "classpath:/templates/";
/** Pattern relative to templates base used to match JSON templates. */
public static final String JSON_TEMPLATES_RESOLVE_PATTERN = "json/*";
public static final String HTML_TEMPLATES_RESOLVE_PATTERN = "html/*";
/**
* Creates the template resolver that retrieves text message payloads.
*
* @return Template resolver.
*/
@Autowired
ThymeleafRemoteResourceResolver thymeRemoteConfig;
/**
* Creates the template resolver that retrieves JSON message payloads.
*
* @return Template resolver.
*/
@Bean
public SpringResourceTemplateResolver jsonMessageTemplateResolver() {
SpringResourceTemplateResolver theResourceTemplateResolver = new SpringResourceTemplateResolver();
theResourceTemplateResolver.setPrefix(TEMPLATES_BASE);
theResourceTemplateResolver.setResolvablePatterns(Collections.singleton(JSON_TEMPLATES_RESOLVE_PATTERN));
theResourceTemplateResolver.setSuffix(".json");
/*
* There is no json template mode so the next line has been commented out. Thymeleaf will recognize the ".json"
* template resource suffix so there is no need to set a template mode.
*/
// theResourceTemplateResolver.setTemplateMode("json");
theResourceTemplateResolver.setCharacterEncoding("UTF-8");
theResourceTemplateResolver.setCacheable(false);
theResourceTemplateResolver.setOrder(2);
return theResourceTemplateResolver;
}
/**
* Creates the template resolver that retrieves JSON message payloads.
*
* @return Template resolver.
*/
@Bean
public SpringResourceTemplateResolver htmlMessageTemplateResolver() {
SpringResourceTemplateResolver theResourceTemplateResolver = new SpringResourceTemplateResolver();
theResourceTemplateResolver.setPrefix(TEMPLATES_BASE);
theResourceTemplateResolver.setResolvablePatterns(Collections.singleton(HTML_TEMPLATES_RESOLVE_PATTERN));
theResourceTemplateResolver.setSuffix(".html");
/*
* There is no json template mode so the next line has been commented out. Thymeleaf will recognize the ".json"
* template resource suffix so there is no need to set a template mode.
*/
// theResourceTemplateResolver.setTemplateMode("json");
theResourceTemplateResolver.setCharacterEncoding("UTF-8");
theResourceTemplateResolver.setCacheable(false);
theResourceTemplateResolver.setOrder(2);
return theResourceTemplateResolver;
}
/**
* Creates the template engine for all message templates.
*
* @param inTemplateResolvers
* Template resolver for different types of messages etc. Note that any template resolvers defined
* elsewhere will also be included in this collection.
* @return Template engine.
*/
@Bean
public SpringTemplateEngine messageTemplateEngine(
final Collection<SpringResourceTemplateResolver> inTemplateResolvers) {
final SpringTemplateEngine theTemplateEngine = new SpringTemplateEngine();
for (SpringResourceTemplateResolver theTemplateResolver : inTemplateResolvers) {
theTemplateEngine.addTemplateResolver(theTemplateResolver);
theTemplateEngine.addTemplateResolver(thymeRemoteConfig);
}
return theTemplateEngine;
}
}

View file

@ -1,63 +0,0 @@
package dev.activitypub.activitypubbot;
// From: https://github.com/RAJNISH3/ThymeLeafApp/blob/master/src/main/java/com/sample/thymeleaf/ThymeleafRemoteResourceResolver.java
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Map;
import org.springframework.stereotype.Service;
import org.thymeleaf.IEngineConfiguration;
import org.thymeleaf.templateresolver.StringTemplateResolver;
import org.thymeleaf.templateresource.ITemplateResource;
@Service
public class ThymeleafRemoteResourceResolver extends StringTemplateResolver {
private final static String PREFIX = "";
public ThymeleafRemoteResourceResolver() {
setResolvablePatterns(Collections.singleton("*"));
}
@Override
protected ITemplateResource computeTemplateResource(IEngineConfiguration configuration, String ownerTemplate,
String template, Map<String, Object> templateResolutionAttributes) {
// ThymeleafTemplate is our internal object that contains the content.
// You should change this to match you're set up.
//InputStream inp = this.getClass().getResourceAsStream("/templates/text/personalDetails.txt");//text
InputStream inp = this.getClass().getResourceAsStream("/templates/text/personalDtlsLoop.txt");
//Thread.currentThread().getContextClassLoader().getResourceAsStream("/templates/text/personalDetails.txt");
String s1 = null;
try {
s1 = convertInputStreamToString(inp);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (inp != null) {
return super.computeTemplateResource(configuration, "txt", s1,
templateResolutionAttributes);
}
return null;
}
private static String convertInputStreamToString(InputStream inputStream)
throws IOException {
ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) != -1) {
result.write(buffer, 0, length);
}
return result.toString(StandardCharsets.UTF_8.name());
}
}