Browse Source

Merge branch 'main' into lang_de, working on further translations

lang_de
Stephan Richter 3 years ago
parent
commit
b6e33c2119
  1. 2
      pom.xml
  2. 4
      src/main/java/de/srsoftware/widerhall/Configuration.java
  3. 22
      src/main/java/de/srsoftware/widerhall/web/Rest.java
  4. 8
      src/main/java/de/srsoftware/widerhall/web/TemplateServlet.java
  5. 80
      src/main/java/de/srsoftware/widerhall/web/Web.java
  6. 6
      src/test/java/de/srsoftware/widerhall/data/DatabaseTest.java
  7. 24
      static/templates/add_list.st
  8. 2
      static/templates/footer.st
  9. 29
      static/templates/frontpage.st
  10. 2
      static/templates/index.st
  11. 2
      static/templates/inspect.st
  12. 4
      static/templates/js.st
  13. 4
      static/templates/listadminlist.st
  14. 10
      static/templates/listlist.st
  15. 6
      static/templates/listmembers.st
  16. 2
      static/templates/login.st

2
pom.xml

@ -6,7 +6,7 @@
<groupId>org.example</groupId> <groupId>org.example</groupId>
<artifactId>Widerhall</artifactId> <artifactId>Widerhall</artifactId>
<version>0.0.11</version> <version>0.0.12</version>
<build> <build>
<plugins> <plugins>
<plugin> <plugin>

4
src/main/java/de/srsoftware/widerhall/Configuration.java

@ -36,7 +36,7 @@ public class Configuration {
var newVals = (JSONObject) new JSONParser().parse(Files.readString(file.toPath())); var newVals = (JSONObject) new JSONParser().parse(Files.readString(file.toPath()));
data.putAll(newVals); data.putAll(newVals);
} catch (ParseException | IOException e){ } catch (ParseException | IOException e){
LOG.warn("Was not able to load configuration from {}:",file,e); LOG.warn("Konnte Konfiguration nicht aus {} laden:",file,e);
} }
return this; return this;
} }
@ -47,7 +47,7 @@ public class Configuration {
} }
public Configuration save() throws IOException { public Configuration save() throws IOException {
if (file == null) throw new NullPointerException("Cannot save configuration: file is null!"); if (file == null) throw new NullPointerException("Konnte Konfiguration nicht speichern: Datei ist null!");
file.getParentFile().mkdirs(); file.getParentFile().mkdirs();
Files.writeString(file.toPath(),data.toJSONString()); Files.writeString(file.toPath(),data.toJSONString());
return this; return this;

22
src/main/java/de/srsoftware/widerhall/web/Rest.java

@ -213,35 +213,35 @@ public class Rest extends HttpServlet {
return Map.of(SUCCESS,t("Mailing-List '{}' wurde {}!",listEmail,enable ? "aktiviert" : "inaktiviert")); return Map.of(SUCCESS,t("Mailing-List '{}' wurde {}!",listEmail,enable ? "aktiviert" : "inaktiviert"));
} catch (SQLException e) { } catch (SQLException e) {
LOG.error("Aktivieren/Inaktivieren der Mailing-Liste fehlgeschlagen: ",e); LOG.error("Aktivieren/Inaktivieren der Mailing-Liste fehlgeschlagen: ",e);
return Map.of("error",t("Failed to update list '{}'",listEmail)); return Map.of(ERROR,t("Aktualisieren der Liste '{}' fehlgeschlagen!",listEmail));
} }
} }
return Map.of("error",t("You are not allowed to edit '{}'",listEmail)); return Map.of(ERROR,t("Sie haben nicht die Berechtigng, '{}' zu bearbeiten",listEmail));
} }
private Map<String, String> hideList(String listEmail, User user, boolean hide) { private Map<String, String> hideList(String listEmail, User user, boolean hide) {
if (listEmail == null || listEmail.isBlank()) return Map.of(ERROR,"no list email provided!"); if (listEmail == null || listEmail.isBlank()) return Map.of(ERROR,"Keine Listen-Email übergeben!");
if (user.hashPermission(User.PERMISSION_ADMIN) || ListMember.listsOwnedBy(user).contains(listEmail)){ if (user.hashPermission(User.PERMISSION_ADMIN) || ListMember.listsOwnedBy(user).contains(listEmail)){
try { try {
MailingList.load(listEmail).hide(hide); MailingList.load(listEmail).hide(hide);
return Map.of(SUCCESS,t("Mailing list '{}' was {}!",listEmail,hide ? "hidden" : "made public")); return Map.of(SUCCESS,t("Mailing-List '{}' wurde {}!",listEmail,hide ? "versteckt" : "veröffentlicht"));
} catch (SQLException e) { } catch (SQLException e) {
LOG.error("Failed to (un)hide mailing list: ",e); LOG.error("Verstecken/Veröffentlichen der Mailinglist fehlgeschlagen: ",e);
return Map.of("error",t("Failed to update list '{}'",listEmail)); return Map.of("error",t("Aktualisieren der Liste '{}' fehlgeschlagen",listEmail));
} }
} }
return Map.of("error",t("You are not allowed to edit '{}'",listEmail)); return Map.of(ERROR,t("Sie haben nicht die Berechtigng, '{}' zu bearbeiten",listEmail));
} }
private Map testList(String listEmail, User user) { private Map testList(String listEmail, User user) {
if (listEmail == null || listEmail.isBlank()) return Map.of(ERROR,"no list email provided!"); if (listEmail == null || listEmail.isBlank()) return Map.of(ERROR,"Keine Listen-Email übergeben!");
try { try {
MailingList.load(listEmail).test(user); MailingList.load(listEmail).test(user);
return Map.of(SUCCESS,t("Sent test email to {}",user.email())); return Map.of(SUCCESS,t("Test-Email an {} gesendet",user.email()));
} catch (Exception e) { } catch (Exception e) {
LOG.warn("Failed to send test email",e); LOG.warn("Senden der Test-Email fehlgeschlagen",e);
return Map.of(ERROR,t("Failed to send test email to {}",user.email())); return Map.of(ERROR,t("Senden der Test-Email an {} fehlgeschlagen",user.email()));
} }
} }
} }

8
src/main/java/de/srsoftware/widerhall/web/TemplateServlet.java

@ -26,12 +26,12 @@ public abstract class TemplateServlet extends HttpServlet {
protected String loadFile(String filename, HttpServletResponse resp) { protected String loadFile(String filename, HttpServletResponse resp) {
var path = String.join(File.separator,baseDir,"static",filename); var path = String.join(File.separator,baseDir,"static",filename);
var file = new File(path); var file = new File(path);
if (!file.exists()) return t("File {} does not exist!",filename); if (!file.exists()) return t("Datei {} existiert nicht!",filename);
try { try {
var content = Files.readString(file.toPath()); var content = Files.readString(file.toPath());
resp.getWriter().println(content); resp.getWriter().println(content);
} catch (IOException e) { } catch (IOException e) {
return t("Failed to load file '{}'!",filename); return t("Ladend der Datei '{}' fehlgeschlagen!",filename);
} }
return null; return null;
} }
@ -44,10 +44,10 @@ public abstract class TemplateServlet extends HttpServlet {
resp.getWriter().println(template.render()); resp.getWriter().println(template.render());
return null; return null;
} catch (IOException e) { } catch (IOException e) {
return t("Failed to load template '{}'",path); return t("Laden der Vorlage '{}' fehlgeschlagen",path);
} }
} }
return t("No template for path '{}'!",path); return t("Keine Vorlage für den Pfad '{}' vorhanden!",path);
} }
protected void loadTemplates() { protected void loadTemplates() {

80
src/main/java/de/srsoftware/widerhall/web/Web.java

@ -60,7 +60,7 @@ public class Web extends TemplateServlet {
data.put(USER, user); data.put(USER, user);
if (!user.hashPermission(User.PERMISSION_CREATE_LISTS)){ if (!user.hashPermission(User.PERMISSION_CREATE_LISTS)){
data.put(ERROR,t("You are not allowed to create new mailing lists!")); data.put(ERROR,t("Ihnen ist es nicht gestattet, neue Mailinglisten anzulegen!"));
return loadTemplate(ADMIN,data,resp); return loadTemplate(ADMIN,data,resp);
} }
@ -88,17 +88,17 @@ public class Web extends TemplateServlet {
data.put(SMTP_PORT, smtpPort); data.put(SMTP_PORT, smtpPort);
if (name == null || name.isBlank() || email == null || email.isBlank()) { if (name == null || name.isBlank() || email == null || email.isBlank()) {
data.put(ERROR, "List name and address are required!"); data.put(ERROR, "Name und Adresse der Liste sind notwendige Felder!");
return loadTemplate(ADD_LIST, data, resp); return loadTemplate(ADD_LIST, data, resp);
} }
if (!Util.isEmail(email)) { if (!Util.isEmail(email)) {
data.put(ERROR, t("List email ({}) is not a valid email address!", email)); data.put(ERROR, t("Listen-E-Mail-Adresse ({}) ist keine gültige E-Mail-Adresse!", email));
return loadTemplate(ADD_LIST, data, resp); return loadTemplate(ADD_LIST, data, resp);
} }
if (imapHost == null || imapHost.isBlank() || imapUser == null || imapUser.isBlank() || imapPass == null || imapPass.isBlank()) { if (imapHost == null || imapHost.isBlank() || imapUser == null || imapUser.isBlank() || imapPass == null || imapPass.isBlank()) {
data.put(ERROR, "IMAP credentials are required!"); data.put(ERROR, "IMAP-Zugangsdaten sind erforderlich!");
return loadTemplate(ADD_LIST, data, resp); return loadTemplate(ADD_LIST, data, resp);
} }
@ -107,12 +107,12 @@ public class Web extends TemplateServlet {
imapPort = Integer.parseInt(req.getParameter(IMAP_PORT)); imapPort = Integer.parseInt(req.getParameter(IMAP_PORT));
data.put(IMAP_PORT, imapPort); data.put(IMAP_PORT, imapPort);
} catch (NumberFormatException nfe) { } catch (NumberFormatException nfe) {
data.put(ERROR, t("'{}' is not a proper port number!", req.getParameter(IMAP_PORT))); data.put(ERROR, t("'{}' ist keine gültige Port-Nummer!", req.getParameter(IMAP_PORT)));
return loadTemplate(ADD_LIST, data, resp); return loadTemplate(ADD_LIST, data, resp);
} }
if (smtpHost == null || smtpHost.isBlank() || smtpUser == null || smtpUser.isBlank() || smtpPass == null || smtpPass.isBlank()) { if (smtpHost == null || smtpHost.isBlank() || smtpUser == null || smtpUser.isBlank() || smtpPass == null || smtpPass.isBlank()) {
data.put(ERROR, "SMTP credentials are required!"); data.put(ERROR, "SMTP-Zugangsdaten sind erforderlich!");
return loadTemplate(ADD_LIST, data, resp); return loadTemplate(ADD_LIST, data, resp);
} }
@ -120,7 +120,7 @@ public class Web extends TemplateServlet {
smtpPort = Integer.parseInt(req.getParameter(SMTP_PORT)); smtpPort = Integer.parseInt(req.getParameter(SMTP_PORT));
data.put(SMTP_PORT, smtpPort); data.put(SMTP_PORT, smtpPort);
} catch (NumberFormatException nfe) { } catch (NumberFormatException nfe) {
data.put(ERROR, t("'{}' is not a proper port number!", req.getParameter(SMTP_PORT))); data.put(ERROR, t("'{}' ist keine gültige Port-Nummer!", req.getParameter(SMTP_PORT)));
return loadTemplate(ADD_LIST, data, resp); return loadTemplate(ADD_LIST, data, resp);
} }
@ -129,20 +129,20 @@ public class Web extends TemplateServlet {
ListMember.create(list, user, ListMember.STATE_OWNER); ListMember.create(list, user, ListMember.STATE_OWNER);
return redirectTo(INDEX, resp); return redirectTo(INDEX, resp);
} catch (SQLException e) { } catch (SQLException e) {
return t("Failed to create list '{}': {}", name, e.getMessage()); return t("Erzeugen der Liste '{}' fehlgeschlagen: {}", name, e.getMessage());
} }
} }
private String confirm(HttpServletRequest req, HttpServletResponse resp) { private String confirm(HttpServletRequest req, HttpServletResponse resp) {
try { try {
var token = req.getParameter(TOKEN); var token = req.getParameter(TOKEN);
if (token== null || token.isBlank()) return t("Invalid or missing token!"); if (token== null || token.isBlank()) return t("Ungültiger oder fehlender Token!");
var user = ListMember.confirm(token); var user = ListMember.confirm(token);
if (user != null) return loadTemplate(INDEX,Map.of(USER,user.safeMap(),NOTES,"Confirmed list subscription!"),resp); if (user != null) return loadTemplate(INDEX,Map.of(USER,user.safeMap(),NOTES,"Listen-Mitgliedschaft bestätigt!"),resp);
return t("Unknown user or token"); return t("Nutzer oder Token unbekannt");
} catch (Exception e) { } catch (Exception e) {
LOG.debug("Failed to confirm list membership:",e); LOG.debug("Bestätigung des Listen-Abonnements fehlgeschlagen:",e);
return t("Confirmation of list membership failed!"); return t("Bestätigung des Listen-Abonnements fehlgeschlagen!");
} }
} }
@ -188,7 +188,7 @@ public class Web extends TemplateServlet {
return confirm(req,resp); return confirm(req,resp);
case RELOAD: case RELOAD:
loadTemplates(); loadTemplates();
data.put(NOTES,t("Templates have been reloaded")); data.put(NOTES,t("Vorlagen wurden neu geladen"));
path = INDEX; path = INDEX;
case "css": case "css":
case INDEX: case INDEX:
@ -199,16 +199,16 @@ public class Web extends TemplateServlet {
data.put(LIST,listEmail); data.put(LIST,listEmail);
return loadTemplate(path, data, resp); return loadTemplate(path, data, resp);
} }
return t("You are not allowed to subscribe to '{}'!",list.email()); return t("Es ist ihnen nicht gestattet, '{}' zu abonnieren!",list.email());
case "js": case "js":
resp.setContentType("text/javascript"); resp.setContentType("text/javascript");
return loadTemplate(path,data,resp); return loadTemplate(path,data,resp);
case LOGIN: case LOGIN:
try { try {
if (User.noUsers()) return loadTemplate(REGISTER, Map.of(NOTES,t("User database is empty. Create admin user first:")), resp); if (User.noUsers()) return loadTemplate(REGISTER, Map.of(NOTES,t("Nutzer-Datenbank ist leer. Admin-Nutzer wird hiermit angelegt:")), resp);
return loadTemplate(path,null,resp); return loadTemplate(path,null,resp);
} catch (SQLException e) { } catch (SQLException e) {
return "Error reading user database!"; return "Fehler beim Lesen der Datenbank!";
} }
case LOGOUT: case LOGOUT:
req.getSession().invalidate(); req.getSession().invalidate();
@ -231,8 +231,8 @@ public class Web extends TemplateServlet {
private String handleLogin(HttpServletRequest req, HttpServletResponse resp) { private String handleLogin(HttpServletRequest req, HttpServletResponse resp) {
var email = req.getParameter("email"); var email = req.getParameter("email");
var pass = req.getParameter("pass"); var pass = req.getParameter("pass");
if (email == null || pass == null) return loadTemplate("login", Map.of("error",t("Missing username or password!")), resp); if (email == null || pass == null) return loadTemplate("login", Map.of("error",t("Nutzername oder Passwort fehlen!")), resp);
if (!Util.isEmail(email)) return loadTemplate("login", Map.of("error",t("'{}' is not a valid email address!",email)), resp); if (!Util.isEmail(email)) return loadTemplate("login", Map.of("error",t("'{}' ist keine gültige Mailadresse!",email)), resp);
try { try {
var user = User.loadUser(email,pass); var user = User.loadUser(email,pass);
req.getSession().setAttribute("user",user); req.getSession().setAttribute("user",user);
@ -240,10 +240,10 @@ public class Web extends TemplateServlet {
resp.sendRedirect(String.join("/",WEB_ROOT,"admin")); resp.sendRedirect(String.join("/",WEB_ROOT,"admin"));
} catch (Exception e) { } catch (Exception e) {
try { try {
LOG.warn("Static.handleLogin failed:",e); LOG.warn("Static.handleLogin fehlgeschlagen:",e);
Thread.sleep(10000); Thread.sleep(10000);
} finally { } finally {
return loadTemplate("login", Map.of(ERROR,t("Invalid username/password"),EMAIL,email), resp); return loadTemplate("login", Map.of(ERROR,t("Ungültiger Nutzername oder ungültiges Passwort!"),EMAIL,email), resp);
} }
} }
return null; return null;
@ -265,7 +265,7 @@ public class Web extends TemplateServlet {
return unsubscribe(req,resp); return unsubscribe(req,resp);
} }
return t("No handler for path {}!",path); return t("Kein Handler für den Pfad '{}'!",path);
} }
@ -277,7 +277,7 @@ public class Web extends TemplateServlet {
resp.sendRedirect(String.join("/",WEB_ROOT,page)); resp.sendRedirect(String.join("/",WEB_ROOT,page));
return null; return null;
} catch (IOException e) { } catch (IOException e) {
return t("Was not able to redirect to {} page: {}", page, e.getMessage()); return t("Weiterleitung nach {} fehlgeschlagen: {}", page, e.getMessage());
} }
} }
@ -293,15 +293,15 @@ public class Web extends TemplateServlet {
if (email == null || email.isBlank() || if (email == null || email.isBlank() ||
name == null || name.isBlank() || name == null || name.isBlank() ||
pass == null || pass.isBlank() || pass == null || pass.isBlank() ||
pass_repeat == null || pass_repeat.isBlank()) return loadTemplate(REGISTER,Map.of(ERROR,"Fill all fields, please!",NAME,name,EMAIL,email),resp); pass_repeat == null || pass_repeat.isBlank()) return loadTemplate(REGISTER,Map.of(ERROR,"Bitte alle Felder ausfüllen!",NAME,name,EMAIL,email),resp);
if (!pass.equals(pass_repeat)) return loadTemplate(REGISTER,Map.of(ERROR,"Passwords do not match!",NAME,name,EMAIL,email),resp); if (!pass.equals(pass_repeat)) return loadTemplate(REGISTER,Map.of(ERROR,"Passworte stimmen nicht überein!",NAME,name,EMAIL,email),resp);
if (Util.simplePassword(pass)) return loadTemplate(REGISTER,Map.of(ERROR,"Password to short or to simple!",NAME,name,EMAIL,email),resp); if (Util.simplePassword(pass)) return loadTemplate(REGISTER,Map.of(ERROR,"Passwort zu kurz oder zu einfach!",NAME,name,EMAIL,email),resp);
var firstUser = false; var firstUser = false;
try { try {
firstUser = User.noUsers(); firstUser = User.noUsers();
} catch (SQLException e) { } catch (SQLException e) {
return t("Failed to access user database: {}",e.getMessage()); return t("Fehler beim Zugriff auf die Nutzer-Datenbank: {}",e.getMessage());
} }
@ -311,8 +311,8 @@ public class Web extends TemplateServlet {
req.getSession().setAttribute("user",user); req.getSession().setAttribute("user",user);
return redirectTo(INDEX,resp); return redirectTo(INDEX,resp);
} catch (SQLException e) { } catch (SQLException e) {
LOG.warn("Failed to create new user:",e); LOG.warn("Erzeugen des neuen Nutzers fehlgeschlagen:",e);
return t("Failed to create new user: {}",e.getMessage()); return t("Erzeugen des neuen Nutzers fehlgeschlagen: {}",e.getMessage());
} }
} }
@ -330,12 +330,12 @@ public class Web extends TemplateServlet {
var list = MailingList.load(listEmail); var list = MailingList.load(listEmail);
if (list == null){ if (list == null){
data.put(ERROR,"No list provided by form data!"); data.put(ERROR,"Formular-Daten enthalten keine Liste!");
return loadTemplate(SUBSCRIBE,data,resp); return loadTemplate(SUBSCRIBE,data,resp);
} }
if (name == null || name.isBlank() || email == null || email.isBlank()){ if (name == null || name.isBlank() || email == null || email.isBlank()){
data.put(ERROR,"Name and email are required fields for list subscription!"); data.put(ERROR,"Name und E-Mail-Adresse sind für das Abonnieren der Mailingliste erforderlich!");
return loadTemplate(SUBSCRIBE,data,resp); return loadTemplate(SUBSCRIBE,data,resp);
} }
if (pass != null && pass.isBlank()) pass = null; if (pass != null && pass.isBlank()) pass = null;
@ -352,36 +352,36 @@ public class Web extends TemplateServlet {
// success → subscribe // success → subscribe
} catch (InvalidKeyException | SQLException e) { } catch (InvalidKeyException | SQLException e) {
// invalid credentials // invalid credentials
data.put(ERROR,t("'{}' already in database, but with different password!",email)); data.put(ERROR,t("'{}' gibt es schon in der Datenbank, hat dort aber ein anderes Passwort!",email));
return loadTemplate(SUBSCRIBE,data,resp); return loadTemplate(SUBSCRIBE,data,resp);
} }
} }
data.put(USER,user.safeMap()); data.put(USER,user.safeMap());
if (!list.isOpenFor(user)){ if (!list.isOpenFor(user)){
data.put(ERROR,t("You are not allowed to join {}!",list.email())); data.put(ERROR,t("Ihnen ist es nicht gestattet, '{}' zu abonnieren!",list.email()));
return loadTemplate(SUBSCRIBE,data,resp); return loadTemplate(SUBSCRIBE,data,resp);
} }
try { try {
list.requestSubscription(user,skipConfirmation); list.requestSubscription(user,skipConfirmation);
if (skipConfirmation) { if (skipConfirmation) {
data.put(NOTES, t("Successfully subscribed '{}' to '{}'.", user.email(), list.email())); data.put(NOTES, t("'{}' hat die Mailingliste '{}' erfolgreich abonniert.", user.email(), list.email()));
} else { } else {
data.put(NOTES, t("Sent confirmation mail to '{}.", user.email())); data.put(NOTES, t("Bestätigungs-Email wurde an '{} versendet.", user.email()));
} }
return loadTemplate(INDEX,data,resp); return loadTemplate(INDEX,data,resp);
} catch (SQLException sqle) { } catch (SQLException sqle) {
LOG.debug("List subscription failed: ",sqle); LOG.debug("Abonnieren der Liste fehlgeschlagen: ",sqle);
var cause = getCausingException(sqle); var cause = getCausingException(sqle);
int code = cause.getErrorCode(); int code = cause.getErrorCode();
if (code == PRIMARY_KEY_CONSTRAINT) {// user already exists if (code == PRIMARY_KEY_CONSTRAINT) {// user already exists
data.put(ERROR,t("You already are member of this list!",sqle.getMessage())); data.put(ERROR,t("Sie haben diese Liste bereits abonniert!",sqle.getMessage()));
} else data.put(ERROR,t("Subscription failed: {}",sqle.getMessage())); } else data.put(ERROR,t("Abonnieren der Liste fehlgeschlagen: {}",sqle.getMessage()));
return loadTemplate(SUBSCRIBE,data,resp); return loadTemplate(SUBSCRIBE,data,resp);
} catch (MessagingException e) { } catch (MessagingException e) {
LOG.warn("Failed to send request confirmation email:",e); LOG.warn("Senden der Bestätigungs-Email fehlgeschlagen:",e);
data.put(ERROR,t("Failed to send request confirmation email: {}",e.getMessage())); data.put(ERROR,t("Senden der Bestätigungs-Email fehlgeschlagen: {}",e.getMessage()));
return loadTemplate(SUBSCRIBE,data,resp); return loadTemplate(SUBSCRIBE,data,resp);
} }
} }

6
src/test/java/de/srsoftware/widerhall/data/DatabaseTest.java

@ -50,8 +50,8 @@ public class DatabaseTest extends TestCase {
} }
public void testUpdate(){ public void testUpdate(){
assertEquals("UPDATE Test",Database.open().update("Test").sql()); assertEquals("UPDATE Test",Database.open().update("Test").compile().toString());
assertEquals("UPDATE Test SET x = 5",Database.open().update("Test").set("x",5).sql()); assertEquals("UPDATE Test SET x = 5",Database.open().update("Test").set("x",5).compile().toString());
assertEquals("UPDATE Test SET x = 5, y = 6",Database.open().update("Test").set("x",5).set("y",6).sql()); assertEquals("UPDATE Test SET x = 5, y = 6",Database.open().update("Test").set("x",5).set("y",6).compile().toString());
} }
} }

24
static/templates/add_list.st

@ -9,24 +9,24 @@
<body id="login"> <body id="login">
«navigation()» «navigation()»
«userinfo()» «userinfo()»
<h1>Widerhall List Creation</h1> <h1>Widerhall Listen-Erzeugung</h1>
«messages()» «messages()»
<form method="POST" action="add_list"> <form method="POST" action="add_list">
<fieldset> <fieldset>
<legend>List configuration</legend> <legend>Listen-Konfiguration</legend>
<fieldset> <fieldset>
<legend>Basic data</legend> <legend>Basis-Daten</legend>
<label> <label>
<input type="text" name="name" value="«data.name»" id="name" /> <input type="text" name="name" value="«data.name»" id="name" />
List name Name der ML
</label> </label>
<label> <label>
<input type="text" name="email" value="«data.email»" id="email" /> <input type="text" name="email" value="«data.email»" id="email" />
List E-Mail Address Email-Adresse
</label> </label>
</fieldset> </fieldset>
<fieldset> <fieldset>
<legend>IMAP protocol</legend> <legend>IMAP-Protokoll</legend>
<label> <label>
<input type="text" name="imap_host" value="«data.imap_host»" id="imap_host" /> <input type="text" name="imap_host" value="«data.imap_host»" id="imap_host" />
Hostname Hostname
@ -37,15 +37,15 @@
</label> </label>
<label> <label>
<input type="text" name="imap_user" value="«data.imap_user»" id="imap_user" /> <input type="text" name="imap_user" value="«data.imap_user»" id="imap_user" />
Username Benutzername
</label> </label>
<label> <label>
<input type="password" name="imap_pass" value="«data.imap_pass»" id="imap_pass" /> <input type="password" name="imap_pass" value="«data.imap_pass»" id="imap_pass" />
Password Passwort
</label> </label>
</fieldset> </fieldset>
<fieldset> <fieldset>
<legend>SMTP protocol</legend> <legend>SMTP-Protokoll</legend>
<label> <label>
<input type="text" name="smtp_host" value="«data.smtp_host»" id="smtp_host" /> <input type="text" name="smtp_host" value="«data.smtp_host»" id="smtp_host" />
Hostname Hostname
@ -56,14 +56,14 @@
</label> </label>
<label> <label>
<input type="text" name="smtp_user" value="«data.smtp_user»" id="smtp_user" /> <input type="text" name="smtp_user" value="«data.smtp_user»" id="smtp_user" />
Username Benutzername
</label> </label>
<label> <label>
<input type="password" name="smtp_pass" value="«data.smtp_pass»" id="smtp_pass" /> <input type="password" name="smtp_pass" value="«data.smtp_pass»" id="smtp_pass" />
Password Passwort
</label> </label>
</fieldset> </fieldset>
<button type="submit">Save new mailing list</button> <button type="submit">neue ML speichern</button>
</fieldset> </fieldset>
</form> </form>
</body> </body>

2
static/templates/footer.st

@ -1,3 +1,3 @@
<div class="footer"> <div class="footer">
Widerhall Mail Distributor. Get the sources at <a target="_blank" href="https://git.srsoftware.de/StephanRichter/Widerhall">git.srsoftware.de</a> Widerhall Mail-Verteiler. Hol die den Quellcode auf <a target="_blank" href="https://git.srsoftware.de/StephanRichter/Widerhall">git.srsoftware.de</a>
</div> </div>

29
static/templates/frontpage.st

@ -1,39 +1,38 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8" />
<link rel="stylesheet" href="css" /> <link rel="stylesheet" href="css" />
</head> </head>
<body id="login"> <body id="login">
<h1>Widerhall front page</h1> <h1>Widerhall Startseite</h1>
If you are looking for you mailing lists, <a href="web/index">Go to the /web page</a>... Falls du zu den Mailing-Listen willst, <a href="web/index">Gehe zur Seite /web</a>...
<fieldset> <fieldset>
<legend>What is <em>Widerhall</em>?</legend> <legend>Was ist <em>Widerhall</em>?</legend>
<p> <p>
Widerhall is a mailing list system written in Java. Widerhall ist ein in Java geschriebenes Mailing-List-System.
It allows to maintain a set of mailing lists with the option to make (some of) them publicy subscribable. Es erlaubd die Pflege con Mailverteilern mit der Option diese für Jedermann abonnierbar zu machen.
</p> </p>
<p> <p>
<em>Widerhall</em> is very lightweight, as does not include a full email server stack. <em>Widerhall</em> ist sehr leichtgewichtig, da es keinen vollständigen Mailserver enthält.
</p> </p>
</fieldset> </fieldset>
<fieldset> <fieldset>
<legend>Why should I use <em>Widerhall</em>?</legend> <legend>Warum sollte ich <em>Widerhall</em> nutzen?</legend>
<p> <p>
Compared to other mailing list systems, widerhall is very lightweight: Im Vergleich mit anderen Mailing-Listen-Systemen ist <em>Widerhall</em> sehr schlank:
<p> <p>
It contains not mailserver stack. It does not even require you to set up a mailserver! Es enthält keinen eigenen Mailserver. Für <em>Widerhall</em> musst du nichtmal einen eigenen Mailserver aufsetzen!
</p> </p>
</fieldset> </fieldset>
<fieldset> <fieldset>
<legend>How does it work?</legend> <legend>Wie funktioniert das?</legend>
<p> <p>
Widerhall works by just letting you set up any IMAP/SMTP enabled email address with a provider of your choice. Bei Widerhall kannst du einfach eine IMAP/SMTP-fähige Emailadresse bei einem beliebigen Anbierter anlegen.
It then connects to the inbox of you selected email address and watches for incoming messages. Danach verbindet sich Widerhall mit dem Posteingang der entsprechenden Email-Adresse und wartet auf dort eingehende Nachrichten.
Upon message reception, it forwards the message to all subscribers of the mailing list. Sobald eine Nachricht empfangen wird, wird diese an alle Abonnenten der Mailing-Liste weitergeleitet.
</p> </p>
<p> <p>
That's it. Das ist alles.
</p> </p>
</fieldset> </fieldset>
</body> </body>

2
static/templates/index.st

@ -10,7 +10,7 @@
«navigation()» «navigation()»
«userinfo()» «userinfo()»
«messages()» «messages()»
<h1>Widerhall Index page</h1> <h1>Widerhall Index-Seite</h1>
«listlist()» «listlist()»
«footer()» «footer()»
</body> </body>

2
static/templates/inspect.st

@ -10,7 +10,7 @@
«navigation()» «navigation()»
«userinfo()» «userinfo()»
«messages()» «messages()»
<h1>Widerhall '«data.list»' Details</h1> <h1>Widerhall '«data.list»'-Details</h1>
«listmembers()» «listmembers()»
</body> </body>
</html> </html>

4
static/templates/js.st

@ -1,5 +1,5 @@
function addPermission(userEmail,permission){ function addPermission(userEmail,permission){
if (confirm("Really give permission to "+userEmail+"?")){ if (confirm("Wirklich Berechtigung an "+userEmail+" geben?")){
$.post('/api/user/addpermission',{email:userEmail,permissions:permission},reload,'json'); $.post('/api/user/addpermission',{email:userEmail,permissions:permission},reload,'json');
} }
} }
@ -13,7 +13,7 @@ function dropList(listEmail){
} }
function dropPermission(userEmail,permission){ function dropPermission(userEmail,permission){
if (confirm("Really withdraw permission from "+userEmail+"?")){ if (confirm("Wirklich Berechtigung von "+userEmail+" wegnehmen?")){
$.post('/api/user/droppermission',{email:userEmail,permissions:permission},reload,'json'); $.post('/api/user/droppermission',{email:userEmail,permissions:permission},reload,'json');
} }
} }

4
static/templates/listadminlist.st

@ -1,5 +1,5 @@
<fieldset> <fieldset>
<legend>List of (editable) mailinglists</legend> <legend>Liste der (bearbeitbaren) Mailing-Listen</legend>
<table id="listlist"> <table id="listlist">
<tr> <tr>
<th colspan="4">List</th> <th colspan="4">List</th>
@ -19,7 +19,7 @@
<th>User</th> <th>User</th>
</tr> </tr>
</table> </table>
<a href="add_list">Add new mailing list</a> <a href="add_list">Neue Mailing-Liste anlegen</a>
<script type="text/javascript"> <script type="text/javascript">
loadListOfEditableLists(); loadListOfEditableLists();
</script> </script>

10
static/templates/listlist.st

@ -1,11 +1,11 @@
<fieldset> <fieldset>
<legend>List of (public) mailinglists</legend> <legend>Liste der (frei abonnierbaren) Mailing-Listen</legend>
<table id="listlist"> <table id="listlist">
<tr> <tr>
<th>List Name</th> <th>Listen-Name</th>
<th colspan="3">List Address</th> <th colspan="3">Listen-Adresse</th>
<th>State</th> <th>Status</th>
<th>Actions</th> <th>Aktionen</th>
</tr> </tr>
</table> </table>
<script type="text/javascript"> <script type="text/javascript">

6
static/templates/listmembers.st

@ -1,10 +1,10 @@
<fieldset> <fieldset>
<legend>Members of «data.list»</legend> <legend>Abonnenten von «data.list»</legend>
<table id="memberlist"> <table id="memberlist">
<tr> <tr>
<th>Name</th> <th>Name</th>
<th>Email</th> <th>E-Mail</th>
<th>State</th> <th>Status</th>
</tr> </tr>
</table> </table>
<script type="text/javascript"> <script type="text/javascript">

2
static/templates/login.st

@ -9,7 +9,7 @@
<body id="login"> <body id="login">
«navigation()» «navigation()»
«messages()» «messages()»
<h1>Widerhall login</h1> <h1>Widerhall Login</h1>
<form method="POST"> <form method="POST">
<fieldset> <fieldset>
<legend>Login-Daten</legend> <legend>Login-Daten</legend>

Loading…
Cancel
Save