Java-basierte Mailinglisten-Anwendung, die auf IMAP+SMTP aufsetzt, und damit (fast) jede Mailbox in eine Mailingliste verwandeln kann.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

169 lines
5.5 KiB

package de.srsoftware.widerhall.data;
import de.srsoftware.widerhall.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import static de.srsoftware.widerhall.Constants.*;
import static de.srsoftware.widerhall.Constants.VARCHAR;
public class Post {
public static final Logger LOG = LoggerFactory.getLogger(Post.class);
public static final String TABLE_NAME = "Posts";
private static final String FROM_ADDR = "from_addr";
private static final String FROM_NAME = "from_name";
private static final String PARENT = "parent";
private static final String LONG = "LONG";
private static final String DATE = "date";
private static final String FILE = "file";
private static HashMap<String, Post> cache = new HashMap<>();
private String id, fromAddr, fromName, subject, filename;
private MailingList list;
private Post parent;
private Long timestamp;
public Post(String id, MailingList list, String fromAddr, String fromName, String subject, Long timestamp){
this.id = id;
this.list = list;
this.fromAddr = fromAddr;
this.fromName = fromName;
this.subject = subject;
this.timestamp = timestamp;
this.filename = generateFilename();
}
public static Post create(MailingList list, Message message){
try {
var id = message.getHeader("Message-ID")[0].replace("<", "").replace(">", "");
var addr = ((InternetAddress) message.getFrom()[0]);
var fromEmail = addr.getAddress();
var fromName = addr.getPersonal();
if (fromName == null || fromName.isBlank()) fromName = fromEmail.split("@")[0] + "@xxxxxx";
var subject = message.getSubject();
var text = Util.getText(message);
var time = message.getSentDate().getTime();
Post post = new Post(id,list,fromEmail,fromName,subject,time);
Files.writeString(post.file().toPath(),text, StandardCharsets.UTF_8);
return post.save();
} catch (MessagingException | IOException | SQLException e) {
LOG.warn("Failed to create post from {}",message);
}
return null;
}
/**
* create posts table
* @throws SQLException
*/
public static void createTable() throws SQLException {
var sql = new StringBuilder()
.append("CREATE TABLE ").append(TABLE_NAME)
.append(" (")
.append(ID).append(" ").append(VARCHAR).append(" NOT NULL PRIMARY KEY, ")
.append(LIST).append(" ").append(VARCHAR).append(", ")
.append(FROM_ADDR).append(" ").append(VARCHAR).append(", ")
.append(FROM_NAME).append(" ").append(VARCHAR).append(", ")
.append(PARENT).append(" ").append(VARCHAR).append(", ")
.append(SUBJECT).append(" ").append(VARCHAR).append(", ")
.append(DATE).append(" ").append(LONG).append(", ")
.append(FILE).append(" ").append(VARCHAR)
.append(");");
Database.open().query(sql).compile().run();
}
public File file(){
return new File(filename);
}
public static HashSet<Post> find(MailingList list) throws SQLException {
var rs = Database.open().select(TABLE_NAME).where(LIST,list.email()).compile().exec();
try {
var result = new HashSet<Post>();
while (rs.next()) result.add(Post.from(rs));
return result;
} finally {
rs.close();
}
}
private static Post from(ResultSet rs) {
try {
var id = rs.getString(ID);
var post = cache.get(id);
if (post == null) {
var list = MailingList.load(rs.getString(LIST));
post = new Post(id, list, rs.getString(FROM_ADDR), rs.getString(FROM_NAME), rs.getString(SUBJECT), rs.getLong(DATE));
cache.put(id,post);
}
return post;
} catch (SQLException e){
LOG.debug("Failed to load Post from database!",e);
}
return null;
}
private String generateFilename() {
return "/tmp/"+id+".json";
}
public String id() {
return id;
}
public static Post load(String id) throws SQLException {
var rs = Database.open().select(TABLE_NAME).where(ID,id).compile().exec();
try {
if (rs.next()) return Post.from(rs);
} finally {
rs.close();
}
return null;
}
public Map<String,Object> map() {
return Map.of(ID,id,
LIST,list.email(),
FROM_ADDR,fromAddr,
FROM_NAME,fromName,
SUBJECT,subject,
DATE,timestamp,
FILE,filename);
}
public Map<String,Object> safeMap() {
return Map.of(ID,id,
LIST,list.name(),
FROM_NAME,fromName,
SUBJECT,Util.dropEmail(subject),
DATE,timestamp);
}
private Post save() throws SQLException {
Database.open().insertInto(TABLE_NAME).values(map()).compile().run();
return this;
}
public long timestamp(){
return timestamp;
}
}