Re: Patch: Handle distribution lists on alias expansion



On 2001.09.21 13:30 Pawel Salek wrote:
>  Toralf Lund wrote:
>  >the test ought
>  > to be written to cover all cases. You might use
>  > LibBalsaAddressBook::dist_list_mode, of course, but that requires the
>  > address book to be found (is there a way to lookup the address book
>  based
>  > on an address), and it's not really what we want for LDIF/LDAP. In
>  fact,
>  > the "dist list" parameter is fairly meaningless for those as person 
>(or
>  > organization) entries and distribution lists are completely distinct
>  for
>  > those types. What we really want is probably to keep more of the
>  structure
>  > from the address book data.
>   1. If you only can, ignore dist_list_mode. This field is a semi-quick
>  hack.
>   2. You can treat LDIF format as the fundamental one. It is most
>  flexible - and also basically identical to LDAP responses. I am sure
>  one can obtain similar effects with VCARD format, though.
>   3. I would consider adding another class LibBalsaDistList. The address
>  book should have entries which can be ordinary addresses or dist
>  lists.

OK, I've now made an alternative (presumably better) implementation, refer 
to attached patch. I didn't introduce a new class though, but merely added 
another list to LibBalsaAddress, for two reasons:

1. It seemed to me that fewer updates were required that way.
2. LDIF/LDAP entries can, at least in theory, have e-mail addresses _and_ 
"member" references to other entries. It's not clear to me how to handle 
the addresses when they do, though.

TODO:
* Revise "dist_list_mode" logic and index parameter(s). (The code in the 
patch will try to ensure dist_list_mode is "false" at all times for LDIF 
address book, and also return list string unconditionally when member_list 
is set.)
* Optionally strip off list names from the headers when sending messages.
* Find out if libbalsa_address_get_mailbox() needs update, too.

--
- Toralf


Index: src/address-book.c
===================================================================
RCS file: /cvs/gnome/balsa/src/address-book.c,v
retrieving revision 1.41
diff -u -b -r1.41 address-book.c
--- src/address-book.c	2001/08/13 13:17:29	1.41
+++ src/address-book.c	2001/09/24 13:05:01
@@ -606,7 +606,7 @@
     if ( address == NULL )
 	return;
 
-    if ( libbalsa_ab->dist_list_mode && g_list_length(address->address_list) >1) {
+    if ( libbalsa_address_is_dist_list(libbalsa_ab, address) ) {
 
 	listdata[LIST_COLUMN_NAME] = address->full_name;
 	listdata[LIST_COLUMN_ADDRESS] = libbalsa_address_to_gchar(address, -1);
Index: src/balsa-index.c
===================================================================
RCS file: /cvs/gnome/balsa/src/balsa-index.c,v
retrieving revision 1.196
diff -u -b -r1.196 balsa-index.c
--- src/balsa-index.c	2001/09/23 18:04:41	1.196
+++ src/balsa-index.c	2001/09/24 13:05:08
@@ -688,7 +688,7 @@
 {
     gchar buff1[32];
     gchar *text[7];
-    gchar* name_str;
+    gchar *name_str=NULL;
     GtkCTreeNode *node;
     GList *list;
     LibBalsaAddress *addy = NULL;
@@ -723,14 +723,10 @@
 	    addy = message->from;
     }
 
-    if (addy) {
-	if (addy->full_name)
-	    name_str = addy->full_name;
-	else if (addy->address_list)
-	    name_str = addy->address_list->data;
-	else
-	    name_str = "";
-    } else
+    if (addy)
+	name_str=(gchar *)libbalsa_address_get_name(addy);
+    
+    if(!name_str)		/* !addy, or addy contained no name/address */
 	name_str = "";
 
     text[3] = append_dots ? g_strconcat(name_str, ",...", NULL)
@@ -1142,7 +1138,7 @@
 	LibBalsaMessage *message=
 	    LIBBALSA_MESSAGE(gtk_ctree_node_get_row_data(ctree, child));
 
-	if(message && (message->flags & LIBBALSA_MESSAGE_FLAG_NEW) ||
+	if(message && message->flags & LIBBALSA_MESSAGE_FLAG_NEW ||
 	   thread_has_unread(ctree, child)) 
 	    return TRUE;
     }
Index: src/expand-alias.c
===================================================================
RCS file: /cvs/gnome/balsa/src/expand-alias.c,v
retrieving revision 1.22
diff -u -b -r1.22 expand-alias.c
--- src/expand-alias.c	2001/09/06 08:59:38	1.22
+++ src/expand-alias.c	2001/09/24 13:05:14
@@ -39,30 +39,6 @@
 #define CASE_INSENSITIVE_NAME
 
 /*
- * FIXME:  Should this come here?
- * 
- *         By putting it here, we slow it down, because we need to scan
- *         the match for ',' every time.
- *
- *         By putting it in the address books, its faster, but the user
- *         must type '"' to match relevant addresses...
- */
-static gchar *
-make_rfc822(gchar *full_name, gchar *address)
-{
-    gchar *new_str;
-    gint i;
-
-    for (i=0; full_name[i] && (full_name[i] != ','); i++);
-    if (full_name[i]) {
-	new_str = g_strdup_printf("\042%s\042 <%s>", full_name, address);
-	g_message("make_rfc822(): New str [%s]", new_str);
-    } else
-	new_str = g_strdup_printf("%s <%s>", full_name, address);
-    return new_str;
-}
-	
-/*
  * expand_alias_find_match()
  *
  * Takes an emailData structure, and scans the relevent Balsa
@@ -176,8 +152,8 @@
 	    }
 	    addr = LIBBALSA_ADDRESS(search->data);
 	}
-	output = make_rfc822(addr->full_name,
-			     (gchar *) addr->address_list->data);
+	output=libbalsa_address_to_gchar(addr, 0);
+	
 	g_message("expand_alias_find_match(): Found [%s]", addr->full_name);
 	g_list_foreach(match, (GFunc)gtk_object_unref, NULL);
 	
@@ -191,5 +167,4 @@
     if (addy->match)
 	g_message("expand_alias_find_match(): Setting to [%s]", addy->match);
 }
-
 
Index: src/sendmsg-window.c
===================================================================
RCS file: /cvs/gnome/balsa/src/sendmsg-window.c,v
retrieving revision 1.307
diff -u -b -r1.307 sendmsg-window.c
--- src/sendmsg-window.c	2001/09/23 19:15:30	1.307
+++ src/sendmsg-window.c	2001/09/24 13:05:24
@@ -640,20 +640,11 @@
 static void
 update_msg_identity(BalsaSendmsg* msg, LibBalsaIdentity* ident)
 {
-    gchar* tmpstr;
+    gchar* tmpstr=libbalsa_address_to_gchar(ident->address, 0);
     
-
     /* change entries to reflect new identity */
-
-    if (strlen(ident->address->full_name) && 
-        strlen(ident->address->address_list->data)) {
-        tmpstr = g_strdup_printf("%s <%s>", ident->address->full_name, 
-                                 (gchar*)ident->address->address_list->data);
         gtk_entry_set_text(GTK_ENTRY(msg->from[1]), tmpstr);
         g_free(tmpstr);
-    } else {
-        gtk_entry_set_text(GTK_ENTRY(msg->from[1]), ident->address->full_name);
-    }
 
     gtk_entry_set_text(GTK_ENTRY(msg->reply_to[1]), ident->replyto);
     
@@ -1570,8 +1561,7 @@
 	    if (message->from && message->from->address_list)
 		newsubject = g_strdup_printf("%s from %s",
 					     balsa_app.current_ident->forward_string,
-					     (gchar *) message->
-					     from->address_list->data);
+					     libbalsa_address_get_mailbox(message->from, 0));
 	    else
 		newsubject = g_strdup(balsa_app.current_ident->forward_string);
 	} else {
@@ -1591,9 +1581,7 @@
 		newsubject = 
 		    g_strdup_printf("%s %s [%s]",
 				    balsa_app.current_ident->forward_string, 
-				    tmp,
-				    (gchar *) message->
-				    from->address_list->data);
+				    tmp,  libbalsa_address_get_mailbox(message->from, 0));
 	    else {
 		newsubject = 
 		    g_strdup_printf("%s %s", 
@@ -1790,10 +1778,7 @@
     /* From: */
     {
         gchar *from;
-	from = g_strdup_printf("%s <%s>", 
-			       balsa_app.current_ident->address->full_name,
-		 	       (gchar *) balsa_app.current_ident->address->
-                               address_list->data);
+	from = libbalsa_address_to_gchar(balsa_app.current_ident->address, 0);
 	gtk_entry_set_text(GTK_ENTRY(msg->from[1]), from); 
 	g_free(from); 
     } 
Index: libbalsa/address-book-ldif.c
===================================================================
RCS file: /cvs/gnome/balsa/libbalsa/address-book-ldif.c,v
retrieving revision 1.2
diff -u -b -r1.2 address-book-ldif.c
--- libbalsa/address-book-ldif.c	2001/08/24 23:22:41	1.2
+++ libbalsa/address-book-ldif.c	2001/09/24 13:05:25
@@ -264,9 +264,66 @@
     
     if (address->full_name == NULL)
 	address->full_name = g_strdup(_("No-Name"));
+
     return address;
 }
     
+static LibBalsaAddress *find_addr(GList *ab_list, const gchar *id)
+ /* *** Is there a standard function for this? */
+{
+    GList *addr;
+    gchar *cmpId=g_strdup(id);
+    
+    g_strstrip(cmpId);
+    
+    for(addr=ab_list; addr; addr=g_list_next(addr)) {
+	LibBalsaAddress *addr_data=(LibBalsaAddress *)addr->data;
+	gchar *addr_id=g_strdup(addr_data->id);
+
+	g_strstrip(addr_id);
+
+	if(g_strcasecmp(cmpId, addr_id)==0) {
+	    g_free(addr_id);
+	    return addr_data;
+	}
+	g_free(addr_id);
+    }
+
+    g_free(cmpId);
+    
+    return NULL;
+}
+
+
+static void expand_addr_list(LibBalsaAddress *address, GList *ab_list)
+{
+    GList *member=address->address_list;
+    GList *member_list=NULL;
+    
+    while(member) {
+	gchar *member_data=member->data;
+	LibBalsaAddress *ref=find_addr(ab_list, member_data);
+
+	if(ref) {
+	    member_list=g_list_append(member_list, ref);
+	    gtk_object_ref(GTK_OBJECT(ref));
+	    member=g_list_remove(member, member_data);
+	    g_free(member_data);
+	} else
+	    member=g_list_next(member);
+    }
+    address->member_list=member_list;
+}
+
+static void expand_ldif_addr(GList *ab_list)
+{
+    GList *addr;
+    
+    for(addr=ab_list; addr; addr=g_list_next(addr)) {
+	expand_addr_list(addr->data, ab_list);
+    }
+}
+    
 /* FIXME: Could stat the file to see if it has changed since last time 
    we read it 
 */
@@ -376,12 +433,9 @@
 	    continue;
 	}
 
-	if (g_strncasecmp(line, "member:", 2) == 0) {
-	    gchar* str = strstr(line, "mail=");
-	    if(str)
+	if (g_strncasecmp(line, "member:", 7) == 0) {
 		address_list = g_list_append(address_list, 
-					     g_strdup(g_strchug(str+5)));
-
+					 g_strdup(g_strchug(line+7)));
 	    continue;
 	}
 
@@ -401,6 +455,7 @@
 	    address = address_new_prefill(address_list, nickname, givenname,
 					  surname, fullname, organization,id);
 
+
 	    /* FIXME: Split into Firstname and Lastname... */
 
 	    list = g_list_append(list, address);
@@ -412,6 +467,7 @@
 	    g_free(organization);
 	}
     }
+    expand_ldif_addr(list);
 
     list = g_list_sort(list, (GCompareFunc)address_compare);
     addr_ldif->address_list = list;
@@ -433,6 +489,7 @@
     completion_list = g_list_reverse(completion_list);
     g_completion_add_items(addr_ldif->alias_complete, completion_list);
     g_list_free(completion_list);
+    ab->dist_list_mode = FALSE; /* *** Clean up later */
 }
 
 /* build_name:
Index: libbalsa/address-book.c
===================================================================
RCS file: /cvs/gnome/balsa/libbalsa/address-book.c,v
retrieving revision 1.6
diff -u -b -r1.6 address-book.c
--- libbalsa/address-book.c	2001/08/11 11:05:07	1.6
+++ libbalsa/address-book.c	2001/09/24 13:05:26
@@ -262,6 +262,16 @@
 
 }
 
+
+gboolean libbalsa_address_is_dist_list(const LibBalsaAddressBook *ab,
+				       const LibBalsaAddress *address)
+{
+    return (address->member_list!=NULL || 
+	    ab->dist_list_mode && g_list_length(address->address_list)>1);
+}
+
+
+
 static void
 libbalsa_address_book_real_save_config(LibBalsaAddressBook * ab,
 				       const gchar * prefix)
Index: libbalsa/address-book.h
===================================================================
RCS file: /cvs/gnome/balsa/libbalsa/address-book.h,v
retrieving revision 1.6
diff -u -b -r1.6 address-book.h
--- libbalsa/address-book.h	2001/08/11 11:05:07	1.6
+++ libbalsa/address-book.h	2001/09/24 13:05:26
@@ -101,6 +101,7 @@
 GList *libbalsa_address_book_alias_complete(LibBalsaAddressBook * ab, 
 					    const gchar *prefix,
 					    gchar **new_prefix);
-
+gboolean libbalsa_address_is_dist_list(const LibBalsaAddressBook *ab,
+				       const LibBalsaAddress *address);
 #endif
 
Index: libbalsa/address.c
===================================================================
RCS file: /cvs/gnome/balsa/libbalsa/address.c,v
retrieving revision 1.12
diff -u -b -r1.12 address.c
--- libbalsa/address.c	2001/08/15 11:30:02	1.12
+++ libbalsa/address.c	2001/09/24 13:05:26
@@ -77,6 +77,7 @@
     addr->last_name = NULL;
     addr->organization = NULL;
     addr->address_list = NULL;
+    addr->member_list = NULL;
 }
 
 static void
@@ -99,6 +100,10 @@
     g_list_free(addr->address_list);
     addr->address_list = NULL;
 
+    g_list_foreach(addr->member_list, (GFunc) gtk_object_unref, NULL);
+    g_list_free(addr->member_list);
+    addr->member_list = NULL;
+
     if (GTK_OBJECT_CLASS(parent_class)->destroy)
 	(*GTK_OBJECT_CLASS(parent_class)->destroy) (GTK_OBJECT(object));
 }
@@ -164,6 +169,97 @@
     return address;
 }
 
+
+static gboolean needs_quotes(const gchar *str)
+{
+    return (strchr(str, ',')!=NULL); /* *** For now */
+
+}
+
+static gchar *rfc2822_mailbox(const gchar *full_name, gchar *address)
+{
+    gchar *new_str;
+
+    if(full_name && needs_quotes(full_name))
+	new_str = g_strdup_printf("\042%s\042 <%s>", full_name, address);
+    else if(full_name)
+	new_str = g_strdup_printf("%s <%s>", full_name, address);
+    else
+	new_str = g_strdup(address);
+}
+
+
+static gchar *rfc2822_group(const gchar *full_name, GList *addr_list)
+{
+    gchar *tmp_str;
+    GString *str = g_string_new("");
+    GList *addr_entry;
+
+    if(full_name) { 
+	if(needs_quotes(full_name))
+	    g_string_sprintf(str, "\042%s\042: ", full_name);
+	else
+	    g_string_sprintf(str, "%s: ", full_name);
+    }
+
+    if(addr_list) {
+	tmp_str = libbalsa_address_to_gchar(LIBBALSA_ADDRESS(addr_list->data), 0);
+	g_string_append(str, tmp_str);
+	g_free(tmp_str);
+
+	for(addr_entry=g_list_next(addr_list); addr_entry; 
+	    addr_entry=g_list_next(addr_entry)) {
+	    tmp_str = libbalsa_address_to_gchar(LIBBALSA_ADDRESS(addr_entry->data), 0);
+	    g_string_sprintfa(str, ", %s", tmp_str);
+	    g_free(tmp_str);
+	}
+    }
+    if(full_name)
+	g_string_append(str, ";");
+    
+    tmp_str=str->str;
+    g_string_free(str, FALSE);
+    
+    return tmp_str;
+}
+
+
+static gchar *rfc2822_list(GList *list)
+{
+    gchar *retc = NULL; 
+    GString *str;
+    GList *addr_entry;
+    
+    g_return_val_if_fail(list!=NULL, NULL);
+
+    str=g_string_new((gchar *)list->data);
+
+    for(addr_entry=g_list_next(list); addr_entry; 
+	addr_entry=g_list_next(list)) {
+	g_string_sprintfa(str, ", %s", (gchar *)addr_entry->data);
+    }
+    retc=str->str;
+    g_string_free(str, FALSE);
+
+    return retc;
+}
+
+
+
+
+static LibBalsaAddress *find_address(const gchar *addr_str, 
+				     LibBalsaAddress *match_addr)
+{
+    GList *ab_list;             /* To iterate address books   */
+    LibBalsaAddressBook *ab;
+    
+    /* *** TODO: Search all address books or just the one match_addr 
+                 belongs for entries containing addr_str in address list.
+                 Return first one that's not a distribution list. */
+    return NULL;
+}
+
+
 /* 
    Get a string version of this address.
 
@@ -174,41 +270,22 @@
 libbalsa_address_to_gchar(LibBalsaAddress * address, gint n)
 {
     gchar *retc = NULL;
-    gchar *address_string;
-    GList *nth_address;
+    gboolean dist_list = TRUE;
 
     g_return_val_if_fail(LIBBALSA_IS_ADDRESS(address), NULL);
-
-    if ( n == -1 ) {
-	GString *str = NULL;
-
-	nth_address = address->address_list;
-	while ( nth_address ) {
-	    address_string = (gchar *)nth_address->data;
-	    if ( str )
-		g_string_sprintfa(str, ", %s", address_string);
-	    else
-		str = g_string_new(address_string);
-	    nth_address = g_list_next(nth_address);
-	}
 
-	if ( str ) {
-	    retc = str->str;
-	    g_string_free(str, FALSE);
-	} else { 
-	    retc = NULL;
-	}
+    if(address->member_list || (n==-1 && !address->address_list))
+	retc = rfc2822_group(address->full_name, address->member_list);
+    else if(n==-1) {
+	retc = rfc2822_list(address->address_list);
     } else {
+	GList *nth_address;
+
 	nth_address = g_list_nth(address->address_list, n);
-	g_return_val_if_fail(nth_address != NULL, NULL);
 
-	address_string = (gchar*)nth_address->data;
+	g_return_val_if_fail(nth_address != NULL, NULL);
 
-	if (address->full_name) {
-	    retc = g_strdup_printf("%s <%s>", address->full_name, address_string);
-	} else {
-	    retc = g_strdup(address_string);
-	}
+	retc = rfc2822_mailbox(address->full_name, nth_address->data);
     }
     
     return retc;
@@ -253,3 +330,4 @@
 }
 
 #endif
+
Index: libbalsa/address.h
===================================================================
RCS file: /cvs/gnome/balsa/libbalsa/address.h,v
retrieving revision 1.11
diff -u -b -r1.11 address.h
--- libbalsa/address.h	2001/08/15 11:30:02	1.11
+++ libbalsa/address.h	2001/09/24 13:05:26
@@ -74,6 +74,7 @@
      * A list of user@domain.
      */
     GList *address_list;
+    GList *member_list;
 };
 
 struct _LibBalsaAddressClass {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]