mailing list improvements
authoradam <adam@megacz.com>
Sun, 21 Jan 2007 23:10:27 +0000 (23:10 +0000)
committeradam <adam@megacz.com>
Sun, 21 Jan 2007 23:10:27 +0000 (23:10 +0000)
darcs-hash:20070121231027-5007d-53110f9975b5766d0ed5b373b17ce5b56c6ee2ad.gz

src/org/ibex/mail/MailingList.java
src/org/ibex/mail/target/FileBasedMailbox.java
src/org/ibex/mail/target/Mailbox.java
src/org/ibex/mail/target/Script.java

index 4eca2c1..9708118 100644 (file)
@@ -13,12 +13,13 @@ import java.net.*;
 import javax.servlet.*;
 import javax.servlet.http.*;
 
-public class MailingList implements Target, Iterable<MailingList.Subscriber> {
+public class MailingList extends Mailbox.MailboxWrapper {
 
-    // DO NOT move this below the stuff underneath it
-    private MailingList(File path) throws IOException {
+    // FIXME
+    public MailingList(File path, FileBasedMailbox fbm) throws IOException {
+        super(fbm);
         this.path = path;
-        archive = FileBasedMailbox.getFileBasedMailbox(path.getCanonicalPath(), true);
+        this.mailbox = fbm;
         properties = new PropertiesFile(new File(path.getCanonicalPath() + File.separatorChar + "properties"));
         address = new Address(properties.get("address"));
         homepage = properties.get("homepage");
@@ -111,8 +112,8 @@ public class MailingList implements Target, Iterable<MailingList.Subscriber> {
     }
 
     private final File             path;
-    private final FileBasedMailbox archive;
     private final PropertiesFile   properties;
+    private final FileBasedMailbox mailbox;
 
     private final long             secret               = new Random().nextLong();
     public  final Address          address;
@@ -131,38 +132,41 @@ public class MailingList implements Target, Iterable<MailingList.Subscriber> {
 
     // Pooling //////////////////////////////////////////////////////////////////////////////
 
-    
-    public Iterator<Subscriber> iterator() {
-        final File subdir = new File(path.getAbsolutePath() + File.separatorChar + "subscribers");
-        if (!subdir.exists()) subdir.mkdirs();
-        final String[] subs = !subdir.isDirectory() ? new String[0] : subdir.list();
-        return new Iterator<Subscriber>() {
-            int i=0;
-            Subscriber prep = null;
-            public void remove() {
-                try {
-                    new File(subdir.getAbsolutePath() + File.separatorChar + subs[i++]).delete();
-                } catch (Exception e) {
-                    Log.error(MailingList.class, e);
-                }
-            }
-            public boolean hasNext() { if (prep==null) prep = next(); return prep!=null; }
-            public Subscriber next() {
-                if (prep!=null) { Subscriber ret = prep; prep = null; return ret; }
-                while(i<subs.length) {
-                    if (subs[i].indexOf('@')==-1) i++;
-                    else try {
-                        return new Subscriber(new Address(subs[i++]));
-                    } catch (Exception e) {
-                        Log.warn(MailingList.class, e);
-                        continue;
+    public Iterable<Subscriber> subscribers() {
+        return new Iterable<Subscriber>() {
+            public java.util.Iterator<Subscriber> iterator() {
+                final File subdir = new File(path.getAbsolutePath() + File.separatorChar + "subscribers");
+                if (!subdir.exists()) subdir.mkdirs();
+                final String[] subs = !subdir.isDirectory() ? new String[0] : subdir.list();
+                return new java.util.Iterator<Subscriber>() {
+                    int i=0;
+                    Subscriber prep = null;
+                    public void remove() {
+                        try {
+                            new File(subdir.getAbsolutePath() + File.separatorChar + subs[i++]).delete();
+                        } catch (Exception e) {
+                            Log.error(MailingList.class, e);
+                        }
                     }
-                }
-                return null;
+                    public boolean hasNext() { if (prep==null) prep = next(); return prep!=null; }
+                    public Subscriber next() {
+                        if (prep!=null) { Subscriber ret = prep; prep = null; return ret; }
+                        while(i<subs.length) {
+                            if (subs[i].indexOf('@')==-1) i++;
+                            else try {
+                                    return new Subscriber(new Address(subs[i++]));
+                                } catch (Exception e) {
+                                    Log.warn(MailingList.class, e);
+                                    continue;
+                                }
+                        }
+                        return null;
+                    }
+                };
             }
         };
     }
-
+    /*
     private static HashMap<String,MailingList> cache = new HashMap<String,MailingList>();
     public static MailingList getMailingList(String path) throws IOException { return getMailingList(new File(path)); }
     public static MailingList getMailingList(File path) throws IOException {
@@ -171,27 +175,33 @@ public class MailingList implements Target, Iterable<MailingList.Subscriber> {
         if (ret==null) cache.put(path.getCanonicalPath(), ret = new MailingList(path));
         return ret;
     }
-
+    */
     // Methods //////////////////////////////////////////////////////////////////////////////
 
-    public Mailbox getArchive() throws IOException { return archive; }
-
-    public void accept(Message m) throws IOException, MailException {
-        StringBuffer buf = new StringBuffer();
-        m.getBody().getStream().transcribe(buf);
-        Headers head = new Headers.Original(m.headers.getStream());
-        head = head.set("List-Id", one_line_description + "<"+address+">");
-        head = head.set("Subject", properties.get("prefix") + " " + head.get("Subject"));
-        
-        m = Message.newMessage(new Fountain.StringFountain(head.getString()+"\r\n"+buf.toString()));
-        Log.warn(MailingList.class, "archiving list message " + m.subject);
-        getArchive().accept(m);
-
-        for(Subscriber s : this) try {
-            Log.warn(MailingList.class, "  trying " + s.address);
-            SMTP.accept(Message.newMessage(m, m.envelopeFrom, s.address));
-            Log.warn("[list]", "successfully sent to " + s);
-        } catch (Exception e2) { Log.error("[list]", e2); }
+    public void add(Message message) {
+        try {
+            accept(message);
+        } catch (Exception e) { throw new RuntimeException(e); }
+    }
+    public void add(Message message, int flags) { add(message); /* FIXME: flags? */ }
+    public void accept(Message m) throws MailException {
+        try {
+            StringBuffer buf = new StringBuffer();
+            m.getBody().getStream().transcribe(buf);
+            Headers head = new Headers.Original(m.headers.getStream());
+            head = head.set("List-Id", one_line_description + "<"+address+">");
+            head = head.set("Subject", properties.get("prefix") + " " + head.get("Subject"));
+            
+            m = Message.newMessage(new Fountain.StringFountain(head.getString()+"\r\n"+buf.toString()));
+            Log.warn(MailingList.class, "archiving list message " + m.subject);
+            mailbox.accept(m);
+            
+            for(Subscriber s : subscribers()) try {
+                    Log.warn(MailingList.class, "  trying " + s.address);
+                    SMTP.accept(Message.newMessage(m, m.envelopeFrom, s.address));
+                    Log.warn("[list]", "successfully sent to " + s);
+                } catch (Exception e2) { Log.error("[list]", e2); }
+        } catch (Exception e) { throw new RuntimeException(e); }
     }
 
     //public Filter[]     filters  = new Filter[0];
index c2868b3..0e7c6f9 100644 (file)
@@ -21,17 +21,22 @@ public class FileBasedMailbox extends Mailbox.Default {
 
     public static final long MAGIC_DATE = 0;
     private static final char slash = File.separatorChar;
-    private static final WeakHashMap<String,FileBasedMailbox> instances = new WeakHashMap<String,FileBasedMailbox>();
+    private static final WeakHashMap<String,Mailbox> instances = new WeakHashMap<String,Mailbox>();
     public String toString() { return "[FileBasedMailbox " + path.getAbsolutePath() + "]"; }
     public Mailbox slash(String name, boolean create) { return getFileBasedMailbox(path.getAbsolutePath()+slash+name, create); }
 
     // FIXME: should be a File()
-    public static synchronized FileBasedMailbox getFileBasedMailbox(String path, boolean create) {
+    public static synchronized Mailbox getFileBasedMailbox(String path, boolean create) {
         try {
-            FileBasedMailbox ret = instances.get(path);
+            Mailbox ret = instances.get(path);
             if (ret == null) {
                 if (!create && !(new File(path).exists())) return null;
-                instances.put(path, ret = new FileBasedMailbox(new File(path)));
+                if (new File(new File(path)+"/subscribers").exists()) {
+                    ret = new MailingList(new File(path), new FileBasedMailbox(new File(path)));
+                } else {
+                    ret = new FileBasedMailbox(new File(path));
+                }
+                instances.put(path, ret);
             }
             return ret;
         } catch (Exception e) {
@@ -69,7 +74,9 @@ public class FileBasedMailbox extends Mailbox.Default {
         String[] files = path.list();
         for(int i=0; i<files.length; i++) {
             try {
-                if (files[i].indexOf('.') != -1) files[i] = files[i].substring(0, files[i].indexOf('.'));
+                if (files[i].indexOf('.') == -1) continue;
+                if (files[i].charAt(0) == '.') continue;
+                files[i] = files[i].substring(0, files[i].indexOf('.'));
                 int n = Integer.parseInt(files[i]);
                 if (n>=uidNext) uidNext = n;
             } catch(Exception e) { Log.error(this, e); }
@@ -284,8 +291,11 @@ public class FileBasedMailbox extends Mailbox.Default {
         private void banner(HttpServletRequest request, HttpServletResponse response) throws IOException {
             String basename = request.getServletPath();
             String realpath = getServletContext().getRealPath(basename);
+            /*
             MailingList list = MailingList.getMailingList(realpath);
             list.banner(request, response);
+            */
+            banner(request, response);
         }
 
         private void topright(HttpServletRequest request, HttpServletResponse response, String[][] messages) throws IOException {
index f5bf940..13b376f 100644 (file)
@@ -42,7 +42,7 @@ public abstract class Mailbox extends JS.Obj implements Target {
 
     // Thunks ////////////////////////////////////////////////////////////////////////////
 
-    public final    void             accept(Message m) { add(m); }
+    public          void             accept(Message m) { add(m); }
     public          Mailbox.Iterator iterator() { return iterator(Query.all()); }
 
 
@@ -216,5 +216,26 @@ public abstract class Mailbox extends JS.Obj implements Target {
         public static final int ANSWERED = 0x0010;
         public static final int RECENT   = 0x0020;
     }
-    
+
+    public static class MailboxWrapper extends Mailbox {
+        
+        private Mailbox m;
+        public MailboxWrapper(Mailbox m) { this.m = m; }
+
+        public boolean          phantom() { return m.phantom(); }
+        public Mailbox.Iterator iterator(Query q) { return m.iterator(q); }
+        public void             add(Message message) { m.add(message); }
+        public void             add(Message message, int flags) { m.add(message, flags); }
+        public void             move(Query q, Mailbox dest) { m.move(q, dest); }
+        public void             copy(Query q, Mailbox dest) { m.copy(q, dest); }
+        public int              count(Query q) { return m.count(q); }
+        public int              uidNext() { return m.uidNext(); }
+        public void             rename(String newName) { m.rename(newName); }
+        public void             destroy(boolean recursive) { m.destroy(recursive); }
+        public Mailbox          slash(String name, boolean create) { return m.slash(name, create); }
+        public String[]         children() { return m.children(); }
+        public Mailbox.Iterator iterator() { return m.iterator(); }
+        public int              uidValidity()  { return m.uidValidity(); }
+    }
+
 }
index 248700e..616d5ac 100644 (file)
@@ -136,7 +136,7 @@ public class Script extends JS.Obj implements Target {
             } catch (IOException e) { throw new JSExn(e.toString()); }
             case "mail.whitelist": return JSReflection.wrap(org.ibex.mail.protocol.SMTP.whitelist);
             case "mail.my.mailbox":
-                FileBasedMailbox root = FileBasedMailbox.getFileBasedMailbox(Mailbox.STORAGE_ROOT, true);
+                Mailbox root = FileBasedMailbox.getFileBasedMailbox(Mailbox.STORAGE_ROOT, true);
                 return root.slash("user", true).slash("megacz", true);
             case "mail.list": return METHOD;
             //#end
@@ -151,7 +151,7 @@ public class Script extends JS.Obj implements Target {
             String name = JSU.toString(name0);
             try {
                 if (name.equals("url.encode")) return JSU.S(java.net.URLEncoder.encode(JSU.toString(args[0])));
-                if (name.equals("mail.list")) return JSReflection.wrap(MailingList.getMailingList(JSU.toString(args[0])));
+                if (name.equals("mail.list")) return JSReflection.wrap(FileBasedMailbox.getFileBasedMailbox(JSU.toString(args[0]), false));
                 if (name.equals("mail.dir")) {
                     return new org.ibex.js.Directory(new File(JSU.toString(args[0])));
                 }