More fixes, should work now
This commit is contained in:
parent
694ddece28
commit
95ec7be10b
|
@ -25,6 +25,7 @@ dependencies {
|
||||||
implementation("com.kohlschutter.junixsocket:junixsocket-core:2.6.0")
|
implementation("com.kohlschutter.junixsocket:junixsocket-core:2.6.0")
|
||||||
implementation("org.jsoup:jsoup:1.15.3")
|
implementation("org.jsoup:jsoup:1.15.3")
|
||||||
implementation("net.freeutils:jlhttp:2.6")
|
implementation("net.freeutils:jlhttp:2.6")
|
||||||
|
implementation("org.commonmark:commonmark:0.20.0")
|
||||||
compileOnly("org.jetbrains:annotations:23.0.0")
|
compileOnly("org.jetbrains:annotations:23.0.0")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,15 @@ import io.gitlab.jfronny.gitea.helpdesk.gitea.*;
|
||||||
import io.gitlab.jfronny.gitea.helpdesk.mail.*;
|
import io.gitlab.jfronny.gitea.helpdesk.mail.*;
|
||||||
import io.gitlab.jfronny.gitea.helpdesk.web.WebInterface;
|
import io.gitlab.jfronny.gitea.helpdesk.web.WebInterface;
|
||||||
import jakarta.mail.MessagingException;
|
import jakarta.mail.MessagingException;
|
||||||
|
import org.commonmark.parser.Parser;
|
||||||
|
import org.commonmark.renderer.html.HtmlRenderer;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public record UpdateTask(DBInterface db, MailInterface mail, GiteaInterface gitea, WebInterface web) implements Runnable {
|
public record UpdateTask(DBInterface db, MailInterface mail, GiteaInterface gitea, WebInterface web) implements Runnable {
|
||||||
|
private static final Parser MARKDOWN_PARSER = Parser.builder().build();
|
||||||
|
private static final HtmlRenderer MARKDOWN_RENDER = HtmlRenderer.builder().build();
|
||||||
private static final String TEMPLATE = Main.getResource("/mail/template.html");
|
private static final String TEMPLATE = Main.getResource("/mail/template.html");
|
||||||
private static final String MAIL_ERROR = Main.getResource("/mail/error.html");
|
private static final String MAIL_ERROR = Main.getResource("/mail/error.html");
|
||||||
private static final String MAIL_UNEXPECTED = Main.getResource("/mail/unexpected.html");
|
private static final String MAIL_UNEXPECTED = Main.getResource("/mail/unexpected.html");
|
||||||
|
@ -42,7 +46,6 @@ public record UpdateTask(DBInterface db, MailInterface mail, GiteaInterface gite
|
||||||
ThrowingBiConsumer<String, String, Exception> reply = (content, subject) -> {
|
ThrowingBiConsumer<String, String, Exception> reply = (content, subject) -> {
|
||||||
String[] previousMessages = subscription.referenceChain().split(" ");
|
String[] previousMessages = subscription.referenceChain().split(" ");
|
||||||
String previousMessageId = previousMessages[previousMessages.length - 1];
|
String previousMessageId = previousMessages[previousMessages.length - 1];
|
||||||
//TODO test
|
|
||||||
mail.reply(addressParts[0] + "+reply+" + subscription.id(), subscription.email(), content, subject, previousMessageId, subscription.referenceChain(), null);
|
mail.reply(addressParts[0] + "+reply+" + subscription.id(), subscription.email(), content, subject, previousMessageId, subscription.referenceChain(), null);
|
||||||
};
|
};
|
||||||
GiteaIssue issue;
|
GiteaIssue issue;
|
||||||
|
@ -53,13 +56,13 @@ public record UpdateTask(DBInterface db, MailInterface mail, GiteaInterface gite
|
||||||
db.removeSubscription(subscription.id());
|
db.removeSubscription(subscription.id());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (issue.state.equals("closed")) { //TODO test
|
if (issue.state.equals("closed")) {
|
||||||
reply.accept(template(MAIL_ISSUE_CLOSED), "Issue closed");
|
reply.accept(template(MAIL_ISSUE_CLOSED), "Issue closed");
|
||||||
db.removeSubscription(subscription.id());
|
db.removeSubscription(subscription.id());
|
||||||
}
|
}
|
||||||
for (GiteaIssueComment comment : gitea.getComments(subscription.repoOwner(), subscription.repo(), subscription.issue())) {
|
for (GiteaIssueComment comment : gitea.getComments(subscription.repoOwner(), subscription.repo(), subscription.issue())) {
|
||||||
if (comment.id > subscription.issueComment()) {
|
if (comment.id > subscription.issueComment()) {
|
||||||
reply.accept(comment.body, issue.title);
|
reply.accept(MARKDOWN_RENDER.render(MARKDOWN_PARSER.parse(comment.body)), issue.title);
|
||||||
db.updateSubscriptionIssueComment(subscription.id(), comment.id);
|
db.updateSubscriptionIssueComment(subscription.id(), comment.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,19 +82,20 @@ public record UpdateTask(DBInterface db, MailInterface mail, GiteaInterface gite
|
||||||
String repo = args[2];
|
String repo = args[2];
|
||||||
checkArgs(owner, repo);
|
checkArgs(owner, repo);
|
||||||
GiteaIssue issue = gitea.createIssue(owner, repo, message.getSubject(), formatBody(message));
|
GiteaIssue issue = gitea.createIssue(owner, repo, message.getSubject(), formatBody(message));
|
||||||
String id = db.addSubscription(message.getSender(), owner, repo, issue.id, 0, message.getSender(), true);
|
String id = db.addSubscription(message.getSender(), owner, repo, issue.id, 0, message.getMessageID(), true);
|
||||||
String unsubscribeUrl = web.getAddress() + "/unsubscribe?id=" + id; //TODO test
|
String unsubscribeUrl = web.getAddress() + "/unsubscribe?id=" + id;
|
||||||
message.reply(addressParts[0] + "+reply+" + owner + "+" + repo + "+" + issue.id + '@' + addressParts[1], template(MAIL_CREATE.formatted(issue.url, unsubscribeUrl)));
|
String closeUrl = web.getAddress() + "/close?id=" + id;
|
||||||
|
message.reply(addressParts[0] + "+reply+" + id + '@' + addressParts[1], template(MAIL_CREATE.formatted(issue.url, unsubscribeUrl, closeUrl)));
|
||||||
}
|
}
|
||||||
case "reply" -> {
|
case "reply" -> {
|
||||||
if (args.length != 2) throw new UnexpectedMailException("Reply classifier only allows one parameter");
|
if (args.length != 2) throw new UnexpectedMailException("Reply classifier only allows one parameter");
|
||||||
Subscription sub = db.getSubscription(args[1]).orElseThrow(() -> new UnexpectedMailException("Reply classifier does not represent an active issue"));
|
Subscription sub = db.getSubscription(args[1]).orElseThrow(() -> new UnexpectedMailException("Reply classifier does not represent an active issue"));
|
||||||
GiteaIssueComment commentId = gitea.addComment(sub.repoOwner(), sub.repo(), sub.issue(), formatBody(message));
|
GiteaIssueComment commentId = gitea.addComment(sub.repoOwner(), sub.repo(), sub.issue(), formatBody(message));
|
||||||
db.updateSubscriptionIssueComment(sub.id(), commentId.id);
|
db.updateSubscriptionIssueComment(sub.id(), commentId.id);
|
||||||
db.updateSubscriptionReferenceChain(sub.id(), sub.referenceChain() + " " + message.getSender());
|
db.updateSubscriptionReferenceChain(sub.id(), sub.referenceChain() + " " + message.getMessageID());
|
||||||
}
|
}
|
||||||
case "comment" -> {
|
case "comment" -> {
|
||||||
if (args.length == 4) throw new UnexpectedMailException("Comment classifier requires four parameters");
|
if (args.length != 4) throw new UnexpectedMailException("Comment classifier requires four parameters");
|
||||||
String owner = args[1];
|
String owner = args[1];
|
||||||
String repo = args[2];
|
String repo = args[2];
|
||||||
long issueId = Long.parseLong(args[3]);
|
long issueId = Long.parseLong(args[3]);
|
||||||
|
@ -102,13 +106,13 @@ public record UpdateTask(DBInterface db, MailInterface mail, GiteaInterface gite
|
||||||
} catch (FileNotFoundException fe) {
|
} catch (FileNotFoundException fe) {
|
||||||
throw new UnexpectedMailException("This issue does not exist");
|
throw new UnexpectedMailException("This issue does not exist");
|
||||||
}
|
}
|
||||||
gitea.addComment(owner, repo, issueId, formatBody(message));
|
long issueComment = gitea.addComment(owner, repo, issueId, formatBody(message)).id;
|
||||||
if (issue.state.equals("closed")) {
|
if (issue.state.equals("closed")) {
|
||||||
message.reply(addressParts[0] + "+reply+" + owner + "+" + repo + "+" + issue.id + '@' + addressParts[1], template(MAIL_COMMENT_CLOSED.formatted(issue.url)));
|
message.reply(mail.getAddress(), template(MAIL_COMMENT_CLOSED.formatted(issue.url)));
|
||||||
} else {
|
} else {
|
||||||
String id = db.addSubscription(message.getSender(), owner, repo, issue.id, 0, message.getSender(), false);
|
String id = db.addSubscription(message.getSender(), owner, repo, issue.id, issueComment, message.getMessageID(), false);
|
||||||
String unsubscribeUrl = web.getAddress() + "/unsubscribe?id=" + id; //TODO test
|
String unsubscribeUrl = web.getAddress() + "/unsubscribe?id=" + id;
|
||||||
message.reply(addressParts[0] + "+reply+" + owner + "+" + repo + "+" + issue.id + '@' + addressParts[1], template(MAIL_COMMENT.formatted(issue.url, unsubscribeUrl)));
|
message.reply(addressParts[0] + "+reply+" + id + '@' + addressParts[1], template(MAIL_COMMENT.formatted(issue.url, unsubscribeUrl)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default -> throw new UnexpectedMailException("Did not expect classifier " + args[0]);
|
default -> throw new UnexpectedMailException("Did not expect classifier " + args[0]);
|
||||||
|
|
|
@ -21,22 +21,22 @@ public class DBInterface implements AutoCloseable {
|
||||||
try (Connection cx = ds.getConnection()) {
|
try (Connection cx = ds.getConnection()) {
|
||||||
try (Statement st = cx.createStatement()) {
|
try (Statement st = cx.createStatement()) {
|
||||||
st.executeUpdate("""
|
st.executeUpdate("""
|
||||||
CREATE EXTENSION pgcrypto;
|
create extension if not exists pgcrypto;
|
||||||
CREATE OR REPLACE FUNCTION helpdesk_generate_uid(size INT) RETURNS TEXT AS $$
|
create or replace function helpdesk_generate_uid(size int) returns text as $$
|
||||||
DECLARE
|
declare
|
||||||
characters TEXT := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
characters text := 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
bytes BYTEA := gen_random_bytes(size);
|
bytes bytea := gen_random_bytes(size);
|
||||||
l INT := length(characters);
|
l int := length(characters);
|
||||||
i INT := 0;
|
i int := 0;
|
||||||
output TEXT := '';
|
output text := '';
|
||||||
BEGIN
|
BEGIN
|
||||||
WHILE i < size LOOP
|
while i < size loop
|
||||||
output := output || substr(characters, get_byte(bytes, i) % l + 1, 1);
|
output := output || substr(characters, get_byte(bytes, i) % l + 1, 1);
|
||||||
i := i + 1;
|
i := i + 1;
|
||||||
END LOOP;
|
end loop;
|
||||||
RETURN output;
|
return output;
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql VOLATILE;
|
$$ language plpgsql volatile;
|
||||||
create table if not exists helpdesk_subscriptions(
|
create table if not exists helpdesk_subscriptions(
|
||||||
id text primary key default helpdesk_generate_uid(20),
|
id text primary key default helpdesk_generate_uid(20),
|
||||||
email text,
|
email text,
|
||||||
|
|
|
@ -66,7 +66,7 @@ public class MailInterface implements AutoCloseable {
|
||||||
MimeMessage reply = new MimeMessage(smtp);
|
MimeMessage reply = new MimeMessage(smtp);
|
||||||
reply.setFrom(from);
|
reply.setFrom(from);
|
||||||
reply.addRecipients(Message.RecipientType.TO, to);
|
reply.addRecipients(Message.RecipientType.TO, to);
|
||||||
reply.setSubject(subject.startsWith("Re: ") ? subject : "Re: " + subject);
|
reply.setSubject(subject == null ? "Reply" : subject.startsWith("Re: ") ? subject : "Re: " + subject);
|
||||||
|
|
||||||
final MimeBodyPart textPart = new MimeBodyPart();
|
final MimeBodyPart textPart = new MimeBodyPart();
|
||||||
textPart.setContent(Jsoup.parse(content).text(), "text/plain");
|
textPart.setContent(Jsoup.parse(content).text(), "text/plain");
|
||||||
|
|
|
@ -91,6 +91,10 @@ public class WrappedMessage {
|
||||||
return "Sender Suppressed";
|
return "Sender Suppressed";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getMessageID() throws MessagingException {
|
||||||
|
return message.getMessageID();
|
||||||
|
}
|
||||||
|
|
||||||
public void reply(String from, String content) throws MessagingException {
|
public void reply(String from, String content) throws MessagingException {
|
||||||
mail.reply(
|
mail.reply(
|
||||||
from,
|
from,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<h1>Successfully added issue</h1>
|
<h1>Successfully added issue</h1>
|
||||||
<p>You can find your new issue <a href="%s">here</a></p>
|
<p>You can find your new issue <a href="%s">here</a></p>
|
||||||
<p>If you wish to unsubscribe from new comments, you may do so <a href="%s">here</a></p>
|
<p>If you wish to unsubscribe from new comments, you may do so <a href="%s">here</a></p>
|
||||||
<p>Please be aware that you will not be sent these a second time!</p>
|
<p>Please be aware that you will not be sent these a second time!</p>
|
||||||
|
<p>If this was a mistake or you resolved the issue yourself, you can close it <a href="%s">here</a></p>
|
|
@ -1,2 +1,3 @@
|
||||||
<h1>This issue was moved or deleted</h1>
|
<h1>This issue was moved or deleted</h1>
|
||||||
<p>This issue was moved or deleted and is no longer accessible</p>
|
<p>This issue was moved or deleted and is no longer accessible</p>
|
||||||
|
<p>Your subscription has therefore been removed</p>
|
Loading…
Reference in New Issue