/*
ZZMbox.java
*
* Copyright (c) 2000, Ted Nelson, Tuomas Lukka and Vesa Parkkinen
*
* You may use and distribute under the terms of either the GNU Lesser
* General Public License, either version 2 of the license or,
* at your choice, any later version. Alternatively, you may use and
* distribute under the terms of the XPL.
*
* See the LICENSE.lgpl and LICENSE.xpl files for the specific terms of
* the licenses.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the README
* file for more details.
*
*/
/*
* Written by Tuomas Lukka and Vesa Parkkinen
*/
package org.gzigzag.module;
import org.gzigzag.*;
import java.util.*;
import java.text.*; // DateFormat
import java.io.*;
import java.awt.*;
import gnu.regexp.*;
/** A mailbox file reader.
*
* AAAAAAAARGGGGGGGGGGHHHHH!!!!!! How to do 8-bit cleanliness and
* internationalization correctly? It's still just a stream of bytes
* that we have underneath. Should probably use encoding when converting
* bytescroll stuff to strings. Gnnnh...
*
* The way to test this is:
*
- Put a path to the mbox to a cell, put right-hand cursor in it and
* execute ZZMbox.READMBOX
*
*
* TODO:
- put all headers somewhere (sorted)
* - more ways to connect messages (references?)
* - smart way to move in threads
*
*/
public class ZZMbox {
public static final String rcsid = "$Id: ZZMbox.java,v 1.1 2002/10/07 12:37:34 tuukkah Exp $";
public static boolean dbg = false;
static final void p(String s) { if(dbg) ZZLogger.log(s); }
static final void pa(String s) { ZZLogger.log(s); }
static ZZCell byDate;
static ZZCell bySender;
static ZZCell bySubject;
static ZZCell byId;
static Hashtable hash = new Hashtable();
static public ZZModule module = new ZZModule() {
public void action(String id, ZZCell code,
ZZCell target,
ZZView v, ZZView cv,
String key, Point pt,
ZZScene xi) {
try {
ZZCell viewCell = v.getViewcell();
ZZCell viewCursor = ZZCursorReal.get(viewCell);
p("ZZMbox ACTION!");
if(id.equals("CREATEFLOBWINDOW")) {
// paths are:
//
// Date:
// handle -> Date: (d.handle)
// headcell(d.clone, -1)
// d.order +1
//
// From: same
// Subject: same
String[] fields = new String[] {
"Subject", "From", "Date", "ARDate"
};
ZZCell mli = viewCell.getHomeCell().N("d.2", 1);
mli.setText("MailflobDims");
ZZCell dlc = mli.N("d.1", 1);
ZZCell odlc = dlc;
ZZCell[] flobdims = new ZZCell[fields.length];
for(int i=0; i= scr.curEnd()) {
i = (int)(scr.curEnd()-offs-1);
}
s = scr.getString(offs, i);
ind = s.indexOf('\n');
}
if(ind<0 && offs != scr.curEnd()) {
p("Problem: no newline at end!");
//return null;
s = scr.getString(offs, (int)scr.curEnd());
offs = scr.curEnd();
return s;
}
s = s.substring(0, ind); // nl not included
offs += ind+1;
return s;
}
long hlstart;
long hlend;
String getHdrLine() throws Exception {
//p("Gethdrline");
hlstart = offs;
long o0 = offs;
String s = getLine();
if(s.equals("")) { // Start of body
return null;
}
if(startws==null)
startws = new RE("^\\s");
if(startws.getMatch(s, 0, RE.REG_ANCHORINDEX)!=null) {
throw new ZZError("ARGH! Invalid header");
}
while(true) {
o0 = offs;
String extra = getLine();
if(startws.getMatch(extra, 0, RE.REG_ANCHORINDEX)
== null) break;
s += extra;
p("Hdrline reloop "+extra);
}
//p("Hdrline end "+s);
offs = o0;
hlend = offs-2;
return s;
}
boolean was_empty = false;
String getBodyLine() throws Exception {
p("Getbody");
long o0 = offs;
String s = getLine();
if( s == null ) return null;
if(startfrom==null)
startfrom =
new RE("^From (.+) (... ... .. ..:..:.. ....)(.*)");
if(startfrom.getMatch(s, 0, RE.REG_ANCHORINDEX)!=null &&
was_empty) {
p("GETBODY: END BODY " + s);
offs = o0;
return null;
}
p("GETBODYRET: "+s);
if ( s.equals("")){
was_empty = true;
} else {
was_empty = false;
}
return s;
}
Span sp(long offs, REMatch m, int i) {
return sp(offs, m.getSubStartIndex(i),
m.getSubEndIndex(i));
}
Span sp(long offs, long i1, long i2) {
return sp(i1+offs, i2+offs);
}
Span sp(long i1, long i2) {
return Span.create(Address.scrollOffs(scr, i1),
Address.scrollOffs(scr, i2));
}
void dohoriz(ZZCell c, long o, REMatch m, int n) {
for(int i=1; i')+1);
}
catch( StringIndexOutOfBoundsException e ){
//irt = hparm;
//pa("NOT VALID: " + hparm);
irt = "";
}
if (! irt.equals("") ){
cur = cur.N("d.handle", 1);
cur.setText("In-Reply-To:");
ar = cur.N("d.1", 1);
ZZCell tmp = byId;
ZZCell repliedTo = (ZZCell)ids.get(irt);
if ( repliedTo == null ){
//create empty cell
//pa("REPLIED MESSAGE NOT IN HASH");
repliedTo = byId.N("d.byfield", 1);
repliedTo.setText(irt);
ar.setText(irt);
ids.put(irt, repliedTo);
}
repliedTo.insert("d.clone", 1, ar);
}
}
else if( hid.equals("References")) {
// if no i-r-t
if ( irt != null ){
irt = hparm;
//p("IRT = " + irt );
try {
irt = irt.substring(irt.lastIndexOf('<'),
irt.lastIndexOf('>')+1);
}
catch( StringIndexOutOfBoundsException e ){
//irt = hparm;
//pa("NOT VALID: " + hparm);
irt = "";
}
if (! irt.equals("") ){
cur = cur.N("d.handle", 1);
cur.setText("In-Reply-To:");
ar = cur.N("d.1", 1);
ZZCell tmp = byId;
ZZCell repliedTo = (ZZCell)ids.get(irt);
if ( repliedTo == null ){
//create empty cell
//pa("REPLIED MESSAGE NOT IN HASH");
repliedTo = byId.N("d.byfield", 1);
repliedTo.setText(irt);
ar.setText(irt);
ids.put(irt, repliedTo);
}
repliedTo.insert("d.clone", 1, ar);
}
}
}
else if( hid.equals("Received" ) && ! received ){
cur = cur.N("d.handle", 1);
cur.setText("ARDate:");
ar = cur.N("d.1", 1);
String dar = hparm;
dar = dar.substring(dar.indexOf(";")+1,
dar.length());
try{
Calendar c =
ZZDateParser.parse(dar);
Date d = c.getTime();
//ar.setText(d.toString());
ar.setText(new SimpleDateFormat().format(d));
}
catch (NumberFormatException nfe){
pa("Not a rfc822 date!");
// XXX interpolate
ar.setText(dar);
ar = ar.N("d.1", 1);
ar.setText("not RFC822 compliant");
}
received = true;
}
}
ZZCell head = fullhdr.N( "d.headers", 1);
head.setSpan(sp(soffs, eoffs-1));
// Finally, handle skewers the body as well.
String b;
long bod = offs;
while((b=getBodyLine())!=null) {
}
cur = cur.N("d.handle",1);
cur.setSpan(sp(bod, offs));
//hcells.addElement(cur);
//pa("TIME USED = " + (System.currentTimeMillis() - t0) );
}
public void run() {
try {
while(offs < scr.curEnd()) {
doMessage();
}
} catch(Exception e) {
p(""+e);
e.printStackTrace();
}
sort();
float date_float = 0;
float subj_float = 0;
float from_float = 0;
ZZCell c = byDate.h("d.byfield" ,-1);
if ( c != null) {
int length = c.getRankLength("d.byfield")-1;
//pa("LENGTH = " + length);
c = c.s("d.byfield", 1);
for(int i = 0; i < length; i++){
c.N("d.order", 1).setText("" + date_float);
date_float += 1.0/length;
c = c.s("d.byfield", 1);
}
}
c = bySubject.h("d.byfield" ,-1);
if ( c != null) {
int length = c.getRankLength("d.byfield") -1;
//pa("LENGTH = " + length);
c = c.s("d.byfield", 1);
for(int i = 0; i < length; i++){
c.N("d.order", 1).setText("" + subj_float);
subj_float = subj_float + ((float)1)/length;
//p("subj_float = " + subj_float );
c = c.s("d.byfield", 1);
}
}
c = bySender.h("d.byfield" ,-1);
if ( c != null) {
int length = c.getRankLength("d.byfield") -1;
//pa("LENGTH = " + length);
c = c.s("d.byfield", 1);
for(int i = 0; i < length; i++){
c.N("d.order", 1).setText("" + from_float);
from_float += 1.0/length;
c = c.s("d.byfield", 1);
}
}
}
}).run();
}
}