Fixed bugs:
- typo on one page - show archive only when public or to moderators Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<groupId>org.example</groupId>
|
<groupId>org.example</groupId>
|
||||||
<artifactId>Widerhall</artifactId>
|
<artifactId>Widerhall</artifactId>
|
||||||
<version>0.2.61</version>
|
<version>1.0.0</version>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
|||||||
@@ -91,6 +91,7 @@ public class Database {
|
|||||||
*/
|
*/
|
||||||
public class Request{
|
public class Request{
|
||||||
|
|
||||||
|
private String groupBy = null;
|
||||||
private final StringBuilder sql; // buffer the sql to be built
|
private final StringBuilder sql; // buffer the sql to be built
|
||||||
private final HashMap<String, List<Object>> where = new HashMap<>(); // buffer condition statements for select
|
private final HashMap<String, List<Object>> where = new HashMap<>(); // buffer condition statements for select
|
||||||
private final HashMap<String,Object> values = new HashMap<>(); // buffer values for insert/update statements
|
private final HashMap<String,Object> values = new HashMap<>(); // buffer values for insert/update statements
|
||||||
@@ -128,33 +129,14 @@ public class Database {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void applyGrouping(){
|
||||||
|
if (groupBy != null && !groupBy.isBlank()) sql.append(" GROUP BY ").append(groupBy.trim());
|
||||||
|
}
|
||||||
|
|
||||||
private void applySorting(){
|
private void applySorting(){
|
||||||
if (!sortFields.isEmpty()) sql.append(" ORDER BY ").append(String.join(", ",sortFields));
|
if (!sortFields.isEmpty()) sql.append(" ORDER BY ").append(String.join(", ",sortFields));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Request clone() {
|
|
||||||
Request clone = new Request(new StringBuilder(sql));
|
|
||||||
clone.where.putAll(where);
|
|
||||||
clone.values.putAll(values);
|
|
||||||
return clone;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* finalize sql, save sql and arguments as compiled request
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public CompiledRequest compile(Object ...additionalArgs){
|
|
||||||
var args = new ArrayList<>();
|
|
||||||
applyValues(args);
|
|
||||||
applyConditions(args);
|
|
||||||
applySorting();
|
|
||||||
if (additionalArgs != null) {
|
|
||||||
for (Object arg : additionalArgs) args.add(arg);
|
|
||||||
}
|
|
||||||
return new CompiledRequest(sql.toString(),args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* apply values (for insert or update statements)
|
* apply values (for insert or update statements)
|
||||||
* @param args
|
* @param args
|
||||||
@@ -188,6 +170,38 @@ public class Database {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Request clone() {
|
||||||
|
Request clone = new Request(new StringBuilder(sql));
|
||||||
|
clone.where.putAll(where);
|
||||||
|
clone.values.putAll(values);
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* finalize sql, save sql and arguments as compiled request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public CompiledRequest compile(Object ...additionalArgs){
|
||||||
|
var args = new ArrayList<>();
|
||||||
|
applyValues(args);
|
||||||
|
applyConditions(args);
|
||||||
|
applyGrouping();
|
||||||
|
applySorting();
|
||||||
|
if (additionalArgs != null) {
|
||||||
|
for (Object arg : additionalArgs) args.add(arg);
|
||||||
|
}
|
||||||
|
return new CompiledRequest(sql.toString(),args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public Request groupBy(String column) {
|
||||||
|
groupBy = column;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public void run() throws SQLException {
|
public void run() throws SQLException {
|
||||||
compile().run();
|
compile().run();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,7 @@ import java.nio.file.Files;
|
|||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
import static de.srsoftware.widerhall.Constants.*;
|
import static de.srsoftware.widerhall.Constants.*;
|
||||||
import static de.srsoftware.widerhall.Constants.VARCHAR;
|
import static de.srsoftware.widerhall.Constants.VARCHAR;
|
||||||
@@ -26,12 +23,13 @@ import static de.srsoftware.widerhall.Constants.VARCHAR;
|
|||||||
public class Post {
|
public class Post {
|
||||||
public static final Logger LOG = LoggerFactory.getLogger(Post.class);
|
public static final Logger LOG = LoggerFactory.getLogger(Post.class);
|
||||||
public static final String TABLE_NAME = "Posts";
|
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 DATE = "date";
|
||||||
private static final String FILE = "file";
|
private static final String FILE = "file";
|
||||||
|
private static final String FROM_ADDR = "from_addr";
|
||||||
|
private static final String FROM_NAME = "from_name";
|
||||||
|
private static final String LONG = "LONG";
|
||||||
|
private static final String PARENT = "parent";
|
||||||
private static HashMap<String, Post> cache = new HashMap<>();
|
private static HashMap<String, Post> cache = new HashMap<>();
|
||||||
|
|
||||||
private String id, fromAddr, fromName, subject, filename;
|
private String id, fromAddr, fromName, subject, filename;
|
||||||
@@ -98,12 +96,13 @@ public class Post {
|
|||||||
return new File(filename);
|
return new File(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ArrayList<Post> find(MailingList list, String month) throws SQLException {
|
public static ArrayList<Post> find(MailingList list, String month, List<String> allowedSenders) throws SQLException {
|
||||||
var rs = Database.open()
|
var query = Database.open()
|
||||||
.select(TABLE_NAME,"*","strftime('%Y-%m',date/1000,'unixepoch') as month")
|
.select(TABLE_NAME,"*","strftime('%Y-%m',date/1000,'unixepoch') as month")
|
||||||
.where(LIST,list.email())
|
.where(LIST,list.email())
|
||||||
.where(MONTH,month)
|
.where(MONTH,month);
|
||||||
.sort(DATE)
|
if (allowedSenders != null) query = query.where(FROM_ADDR,allowedSenders);
|
||||||
|
var rs = query.sort(DATE)
|
||||||
.compile()
|
.compile()
|
||||||
.exec();
|
.exec();
|
||||||
try {
|
try {
|
||||||
@@ -174,10 +173,13 @@ public class Post {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<String, Object> summarize(MailingList list) throws SQLException {
|
public static Map<String, Object> summarize(MailingList list,List<String> limitedUsers) throws SQLException {
|
||||||
var sql = new StringBuilder("SELECT count(*) as count,strftime('%Y-%m',date/1000,'unixepoch') as month FROM Posts WHERE list = ? GROUP BY month ORDER BY month;");
|
var sql = new StringBuilder("SELECT count(*) as count,strftime('%Y-%m',date/1000,'unixepoch') as month FROM Posts");
|
||||||
|
var query = Database.open().query(sql).where(LIST,list.email()).groupBy(MONTH).sort(MONTH);
|
||||||
|
if (limitedUsers != null) query.where(FROM_ADDR,limitedUsers);
|
||||||
|
var rs = query.compile().exec();
|
||||||
|
|
||||||
var map = new TreeMap<String,Object>();
|
var map = new TreeMap<String,Object>();
|
||||||
var rs = Database.open().query(sql).compile(list.email()).exec();
|
|
||||||
while (rs.next()) map.put(rs.getString("month"),rs.getInt("count"));
|
while (rs.next()) map.put(rs.getString("month"),rs.getInt("count"));
|
||||||
rs.close();
|
rs.close();
|
||||||
return map;
|
return map;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.time.Month;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -61,15 +62,16 @@ public class Rest extends HttpServlet {
|
|||||||
return Map.of(SUCCESS,"Nutzer-Berechtigungen aktualisiert");
|
return Map.of(SUCCESS,"Nutzer-Berechtigungen aktualisiert");
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Object> archive(HttpServletRequest req) {
|
private Map<String,Object> archive(MailingList list, String month, User requestingUser){
|
||||||
var list = Util.getMailingList(req);
|
|
||||||
if (list != null){
|
if (list != null){
|
||||||
try {
|
try {
|
||||||
var month = req.getParameter(MONTH);
|
var allEmails = requestingUser != null || list.hasState(STATE_OPEN_FOR_SUBSCRIBERS) || list.hasState(STATE_OPEN_FOR_GUESTS);
|
||||||
|
var limitedSenders = allEmails ? null : list.moderators().map(ListMember::user).map(User::email).toList();
|
||||||
|
|
||||||
if (month == null || month.isBlank()) {
|
if (month == null || month.isBlank()) {
|
||||||
return Map.of(LIST,list.email(),"summary",Post.summarize(list));
|
return Map.of(LIST,list.email(),"summary",Post.summarize(list,limitedSenders));
|
||||||
} else {
|
} else {
|
||||||
return Map.of(LIST,list.email(),"posts",Post.find(list,month).stream().map(Post::safeMap).toList());
|
return Map.of(LIST,list.email(),"posts",Post.find(list,month,limitedSenders).stream().map(Post::safeMap).toList());
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -156,7 +158,14 @@ public class Rest extends HttpServlet {
|
|||||||
json.put(USER,user.safeMap());
|
json.put(USER,user.safeMap());
|
||||||
switch (path) {
|
switch (path) {
|
||||||
case LIST_ARCHIVE:
|
case LIST_ARCHIVE:
|
||||||
json.put("archive",archive(req));
|
var list = Util.getMailingList(req);
|
||||||
|
try {
|
||||||
|
var allowed = list.hasState(STATE_PUBLIC_ARCHIVE) || list.moderators().map(ListMember::user).anyMatch(mod -> user.equals(mod));
|
||||||
|
if (!allowed) return t("Sie sind nicht berechtigt, das Archiv dieser Liste einzusehen!");
|
||||||
|
json.put("archive",archive(list,req.getParameter(MONTH),user));
|
||||||
|
} catch (SQLException sqle){
|
||||||
|
return sqle.getMessage();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case USER_LIST:
|
case USER_LIST:
|
||||||
try {
|
try {
|
||||||
@@ -179,7 +188,10 @@ public class Rest extends HttpServlet {
|
|||||||
} else {
|
} else {
|
||||||
switch (path) {
|
switch (path) {
|
||||||
case LIST_ARCHIVE:
|
case LIST_ARCHIVE:
|
||||||
json.put("archive",archive(req));
|
var list = Util.getMailingList(req);
|
||||||
|
var allowed = list.hasState(STATE_PUBLIC_ARCHIVE);
|
||||||
|
if (!allowed) return t("Diese Liste hat kein öffentliches Archiv!");
|
||||||
|
json.put("archive",archive(list,req.getParameter(MONTH),null));
|
||||||
break;
|
break;
|
||||||
case LIST_SUBSCRIBABLE:
|
case LIST_SUBSCRIBABLE:
|
||||||
json.put("lists", MailingList.subscribable().stream().map(MailingList::minimalMap).toList());
|
json.put("lists", MailingList.subscribable().stream().map(MailingList::minimalMap).toList());
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
<div class="footer">
|
<div class="footer">
|
||||||
Widerhall Mail-Verteiler. Hol dir den Quellcode auf <a target="_blank" href="https://git.srsoftware.de/StephanRichter/Widerhall/src/branch/lang_de">git.srsoftware.de</a>
|
Widerhall Mail-Verteiler. Version 1.0.0 Hol dir den Quellcode auf <a target="_blank" href="https://git.srsoftware.de/StephanRichter/Widerhall/src/branch/lang_de">git.srsoftware.de</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<form method="POST">
|
<form method="POST">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Einstellungen</legend>
|
<legend>Einstellungen</legend>
|
||||||
Diese Seite zeigt Konfigurations-Optionen für die Mailingliste. Um Login-Daten zu ändern, gehe zu <a href="edit_list?list=«data.list»">Listenbarebeitung</a>.
|
Diese Seite zeigt Konfigurations-Optionen für die Mailingliste. Um Login-Daten zu ändern, gehe zu <a href="edit_list?list=«data.list»">Listenbearbeitung</a>.
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Weiterleitungs-Rechte</legend>
|
<legend>Weiterleitungs-Rechte</legend>
|
||||||
<p>
|
<p>
|
||||||
|
|||||||
Reference in New Issue
Block a user