* many: renaming/refactoring

- mu-msg-gmime => mu-msg
  - mu-msg-part-info => mu-msg-part

    removed some unused functions, updated dependencies
    make check still works
This commit is contained in:
djcb 2010-08-25 00:57:16 +03:00
parent f1bbb3fb96
commit 9a510162b5
31 changed files with 932 additions and 1268 deletions

View File

@ -67,13 +67,16 @@ libmu_la_SOURCES= \
mu-msg-fields.h \
mu-msg-flags.c \
mu-msg-flags.h \
mu-msg-gmime.c \
mu-msg-gmime.h \
mu-msg-prio.h \
mu-msg-status.h \
mu-msg.c \
mu-msg.h \
mu-msg-priv.h \
mu-msg-iter-xapian-priv.hh \
mu-msg-iter-xapian.cc \
mu-msg-iter-xapian.h \
mu-msg-part-info.c \
mu-msg-part-info.h \
mu-msg-part.c \
mu-msg-part.h \
mu-msg-str.c \
mu-msg-str.h \
mu-msg.h \

View File

@ -1,5 +1,5 @@
/*
** Copyright (C) 2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify it
** under the terms of the GNU General Public License as published by the
@ -17,27 +17,29 @@
**
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /*HAVE_CONFIG_H*/
#include <stdlib.h>
#include "mu-msg-gmime.h"
#include "mu-msg.h"
#include "mu-msg-part.h"
#include "mu-msg-str.h"
#include "mu-cmd.h"
static gboolean
save_part (const char* path, unsigned idx)
{
MuMsgGMime* msg;
MuMsg* msg;
msg = mu_msg_gmime_new (path, NULL);
msg = mu_msg_new (path, NULL);
if (!msg)
return FALSE;
mu_msg_gmime_mime_part_save (msg, idx, NULL, TRUE); /* FIXME */
mu_msg_mime_part_save (msg, idx, NULL, TRUE); /* FIXME */
mu_msg_gmime_destroy (msg);
mu_msg_destroy (msg);
return TRUE;
}
@ -45,7 +47,7 @@ save_part (const char* path, unsigned idx)
static void
each_part (MuMsgPartInfo* part, gpointer user_data)
each_part (MuMsgPart *part, gpointer user_data)
{
g_print ("%u %s %s/%s [%s]\n",
part->index,
@ -59,15 +61,15 @@ each_part (MuMsgPartInfo* part, gpointer user_data)
static gboolean
show_parts (const char* path)
{
MuMsgGMime* msg;
MuMsg* msg;
msg = mu_msg_gmime_new (path, NULL);
msg = mu_msg_new (path, NULL);
if (!msg)
return FALSE;
mu_msg_gmime_msg_part_infos_foreach (msg, each_part, NULL);
mu_msg_msg_part_foreach (msg, each_part, NULL);
mu_msg_gmime_destroy (msg);
mu_msg_destroy (msg);
return TRUE;
@ -82,12 +84,12 @@ mu_cmd_extract (MuConfigOptions *opts)
/* note: params[0] will be 'view' */
if (!opts->params[0] || !opts->params[1]) {
g_printerr ("missing file to extract\n");
g_warning ("missing mail file to extract something from");
return FALSE;
}
mu_msg_gmime_init();
mu_msg_init();
rv = FALSE;
rv = TRUE;
if (!opts->params[2]) /* no explicit part, show, don't save */
rv = show_parts (opts->params[1]);
else {
@ -95,20 +97,20 @@ mu_cmd_extract (MuConfigOptions *opts)
for (i = 2; opts->params[i]; ++i) {
unsigned idx = atoi (opts->params[i]);
if (idx == 0) {
g_printerr ("not a valid index: %s", opts->params[i]);
g_warning ("not a valid index: %s", opts->params[i]);
rv = FALSE;
break;
}
if (!save_part (opts->params[1], idx)) {
g_printerr ("failed to save part %d of %s", idx,
g_warning ("failed to save part %d of %s", idx,
opts->params[1]);
rv = FALSE;
break;
}
}
}
mu_msg_gmime_uninit();
mu_msg_uninit();
return rv;
}

View File

@ -1,5 +1,5 @@
/*
** Copyright (C) 2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify it
** under the terms of the GNU General Public License as published by the
@ -17,7 +17,9 @@
**
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /*HAVE_CONFIG_H*/
#include <unistd.h>
#include <stdio.h>
@ -26,7 +28,7 @@
#include <stdlib.h>
#include <signal.h>
#include "mu-msg-gmime.h"
#include "mu-msg.h"
#include "mu-maildir.h"
#include "mu-index.h"
#include "mu-query-xapian.h"
@ -74,14 +76,14 @@ display_field (MuMsgIterXapian *iter, const MuMsgField* field)
case MU_MSG_FIELD_TYPE_INT:
if (mu_msg_field_id(field) == MU_MSG_FIELD_ID_PRIORITY) {
if (mu_msg_field_id(field) == MU_MSG_FIELD_ID_PRIO) {
val = mu_msg_iter_xapian_get_field_numeric (iter, field);
return mu_msg_str_prio ((MuMsgPriority)val);
return mu_msg_str_prio ((MuMsgPrio)val);
}
if (mu_msg_field_id(field) == MU_MSG_FIELD_ID_FLAGS) {
val = mu_msg_iter_xapian_get_field_numeric (iter, field);
return mu_msg_str_flags_s ((MuMsgPriority)val);
return mu_msg_str_flags_s ((MuMsgPrio)val);
}
return mu_msg_iter_xapian_get_field (iter, field); /* as string */
@ -120,18 +122,18 @@ static void
print_summary (MuMsgIterXapian *iter, size_t summary_len)
{
const char *summ;
MuMsgGMime *msg;
MuMsg *msg;
msg = mu_msg_iter_xapian_get_msg_gmime (iter);
msg = mu_msg_iter_xapian_get_msg (iter);
if (!msg) {
g_warning ("%s: failed to create msg object", __FUNCTION__);
return;
}
summ = mu_msg_gmime_get_summary (msg, summary_len);
summ = mu_msg_get_summary (msg, summary_len);
g_print ("Summary: %s\n", summ ? summ : "<none>");
mu_msg_gmime_destroy (msg);
mu_msg_destroy (msg);
}
@ -341,19 +343,19 @@ mu_cmd_find (MuConfigOptions *opts)
/* first param is 'query', search params are after that */
params = (const gchar**)&opts->params[1];
mu_msg_gmime_init();
mu_msg_init();
xapian = mu_query_xapian_new (opts->xpath);
if (!xapian) {
g_printerr ("Failed to create a Xapian query\n");
mu_msg_gmime_uninit ();
mu_msg_uninit ();
return FALSE;
}
rv = do_output (xapian, opts, params);
mu_query_xapian_destroy (xapian);
mu_msg_gmime_uninit();
mu_msg_uninit();
return rv;
}

View File

@ -27,7 +27,7 @@
#include "mu-util.h"
#include "mu-util-xapian.h"
#include "mu-msg-gmime.h"
#include "mu-msg.h"
#include "mu-index.h"
#include "mu-cmd.h"
@ -205,13 +205,13 @@ run_index (MuIndex *midx, const char* maildir, MuIndexStats *stats,
MuResult rv;
mu_index_stats_clear (stats);
mu_msg_gmime_init ();
mu_msg_init ();
rv = mu_index_run (midx, maildir, reindex, stats,
quiet ? index_msg_silent_cb :index_msg_cb,
NULL, NULL);
mu_msg_gmime_init ();
mu_msg_init ();
return rv;
}

36
src/mu-cmd-mkdir.h Normal file
View File

@ -0,0 +1,36 @@
/*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify it
** under the terms of the GNU General Public License as published by the
** Free Software Foundation; either version 3, or (at your option) any
** later version.
**
** This program 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
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software Foundation,
** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
*/
#ifndef __MU_CMD_MKDIR_H__
#define __MU_CMD_MKDIR_H__
#include <glib.h>
#include "mu-config.h"
/**
* execute the 'mkdir' command
*
* @param opts configuration options
*
* @return TRUE if the command succeede, FALSE otherwise
*/
gboolean mu_cmd_mkdir (MuConfigOptions *opts);
#endif /*__MU_CMD_VIEW_H__*/

View File

@ -25,7 +25,7 @@
#include <errno.h>
#include <stdlib.h>
#include "mu-msg-gmime.h"
#include "mu-msg.h"
#include "mu-msg-str.h"
#include "mu-cmd.h"
@ -36,41 +36,41 @@
static gboolean
view_file (const gchar *path, const gchar *fields, size_t summary_len)
{
MuMsgGMime* msg;
MuMsg* msg;
const char *field;
time_t date;
msg = mu_msg_gmime_new (path, NULL);
msg = mu_msg_new (path, NULL);
if (!msg)
return FALSE;
field = mu_msg_gmime_get_from (msg);
field = mu_msg_get_from (msg);
if (field)
g_print ("From: %s\n", field);
field = mu_msg_gmime_get_to (msg);
field = mu_msg_get_to (msg);
if (field)
g_print ("To: %s\n", field);
field = mu_msg_gmime_get_cc (msg);
field = mu_msg_get_cc (msg);
if (field)
g_print ("Cc: %s\n", field);
field = mu_msg_gmime_get_subject (msg);
field = mu_msg_get_subject (msg);
if (field)
g_print ("Subject: %s\n", field);
date = mu_msg_gmime_get_date (msg);
date = mu_msg_get_date (msg);
if (date)
g_print ("Date: %s\n",
mu_msg_str_date_s (date));
if (summary_len > 0) {
field = mu_msg_gmime_get_summary (msg, summary_len);
field = mu_msg_get_summary (msg, summary_len);
g_print ("Summary: %s\n", field ? field : "<none>");
} else {
field = mu_msg_gmime_get_body_text (msg);
field = mu_msg_get_body_text (msg);
if (field)
g_print ("\n%s\n", field);
else
@ -78,7 +78,7 @@ view_file (const gchar *path, const gchar *fields, size_t summary_len)
g_debug ("No text body found for %s", path);
}
mu_msg_gmime_destroy (msg);
mu_msg_destroy (msg);
return TRUE;
}
@ -97,14 +97,14 @@ mu_cmd_view (MuConfigOptions *opts)
return FALSE;
}
mu_msg_gmime_init();
mu_msg_init();
rv = TRUE;
for (i = 1; opts->params[i] && rv; ++i)
rv = view_file (opts->params[i], NULL,
opts->summary_len);
mu_msg_gmime_uninit();
mu_msg_uninit();
return rv;
}

28
src/mu-cmd-view.h Normal file
View File

@ -0,0 +1,28 @@
/*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify it
** under the terms of the GNU General Public License as published by the
** Free Software Foundation; either version 3, or (at your option) any
** later version.
**
** This program 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
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software Foundation,
** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
*/
#ifndef __MU_CMD_VIEW_H__
#define __MU_CMD_VIEW_H__
#include <glib.h>
#include "mu-config.h"
#endif /*__MU_CMD_VIEW_H__*/

View File

@ -97,7 +97,7 @@ insert_or_update_maybe (const char* fullpath, const char* mdir,
time_t filestamp,
MuIndexCallbackData *data, gboolean *updated)
{
MuMsgGMime *msg;
MuMsg *msg;
*updated = FALSE;
@ -125,7 +125,7 @@ insert_or_update_maybe (const char* fullpath, const char* mdir,
} while (0);
msg = mu_msg_gmime_new (fullpath, mdir);
msg = mu_msg_new (fullpath, mdir);
if (!msg) {
g_warning ("%s: failed to create mu_msg for %s",
__FUNCTION__, fullpath);
@ -139,7 +139,7 @@ insert_or_update_maybe (const char* fullpath, const char* mdir,
/* ignore...*/
}
mu_msg_gmime_destroy (msg);
mu_msg_destroy (msg);
*updated = TRUE;
return MU_OK;

View File

@ -22,57 +22,110 @@
#endif /*HAVE_CONFIG_H*/
#include <glib.h>
#include <gmime/gmime.h>
#include "mu-msg-priv.h"
#include "mu-msg.h"
#include "mu-msg-contact.h"
#include "mu-util.h"
MuMsgContact*
mu_msg_contact_new (const char *name, const char* address,
MuMsgContactType ctype)
static gboolean
fill_contact (MuMsgContact *contact, InternetAddress *addr,
MuMsgContactType ctype)
{
MuMsgContact *ct;
if (!addr)
return FALSE;
g_return_val_if_fail (ctype == MU_MSG_CONTACT_TYPE_TO ||
ctype == MU_MSG_CONTACT_TYPE_FROM ||
ctype == MU_MSG_CONTACT_TYPE_CC ||
ctype == MU_MSG_CONTACT_TYPE_BCC,
NULL);
contact->name = (char*)internet_address_get_name (addr);
contact->type = ctype;
ct = g_slice_new (MuMsgContact);
ct->name = name ? g_strdup(name) : NULL;
ct->address = address ? g_strdup(address) : NULL;
ct->type = ctype;
return ct;
/* we only support internet addresses;
* if we don't check, g_mime hits an assert
*/
contact->address = (char*)internet_address_mailbox_get_addr
(INTERNET_ADDRESS_MAILBOX(addr));
return TRUE;
}
void
mu_msg_contact_destroy (MuMsgContact *ct)
static void
address_list_foreach (InternetAddressList *addrlist,
MuMsgContactType ctype,
MuMsgContactForeachFunc func,
gpointer user_data)
{
if (ct) {
g_free (ct->name);
g_free (ct->address);
int i;
if (!addrlist)
return;
for (i = 0; i != internet_address_list_length(addrlist); ++i) {
MuMsgContact contact;
if (!fill_contact(&contact,
internet_address_list_get_address (addrlist, i),
ctype)) {
MU_WRITE_LOG ("ignoring contact");
continue;
}
if (!(func)(&contact, user_data))
break;
}
g_slice_free (MuMsgContact, ct);
return;
}
void
mu_msg_contacts_foreach (GSList *lst,
MuMsgContactForeachFunc func,
gpointer user_data)
static void
get_contacts_from (MuMsg *msg, MuMsgContactForeachFunc func,
gpointer user_data)
{
while (lst && func((MuMsgContact*)lst->data, user_data))
lst = g_slist_next(lst);
}
InternetAddressList *lst;
/* we go through this whole excercise of trying to get a *list*
* of 'From:' address (usually there is only one...), because
* internet_address_parse_string has the nice side-effect of
* splitting in names and addresses for us */
lst = internet_address_list_parse_string (
g_mime_message_get_sender (msg->_mime_msg));
if (lst) {
address_list_foreach (lst, MU_MSG_CONTACT_TYPE_FROM,
func, user_data);
g_object_unref (G_OBJECT(lst));
}
}
void
mu_msg_contacts_free (GSList *lst)
mu_msg_contact_foreach (MuMsg *msg, MuMsgContactForeachFunc func,
gpointer user_data)
{
g_slist_foreach (lst, (GFunc)mu_msg_contact_destroy, NULL);
g_slist_free (lst);
int i;
struct {
GMimeRecipientType _gmime_type;
MuMsgContactType _type;
} ctypes[] = {
{GMIME_RECIPIENT_TYPE_TO, MU_MSG_CONTACT_TYPE_TO},
{GMIME_RECIPIENT_TYPE_CC, MU_MSG_CONTACT_TYPE_CC},
{GMIME_RECIPIENT_TYPE_BCC, MU_MSG_CONTACT_TYPE_BCC},
};
g_return_if_fail (func && msg);
/* first, get the from address(es) */
get_contacts_from (msg, func, user_data);
/* get to, cc, bcc */
for (i = 0; i != G_N_ELEMENTS(ctypes); ++i) {
InternetAddressList *addrlist;
addrlist = g_mime_message_get_recipients (msg->_mime_msg,
ctypes[i]._gmime_type);
address_list_foreach (addrlist, ctypes[i]._type, func, user_data);
}
}

View File

@ -21,6 +21,7 @@
#define __MU_MSG_CONTACT_H__
#include <glib.h>
#include "mu-msg.h"
enum _MuMsgContactType { /* Reply-To:? */
MU_MSG_CONTACT_TYPE_TO,
@ -38,28 +39,6 @@ struct _MuMsgContact {
};
typedef struct _MuMsgContact MuMsgContact;
/**
* create a new MuMsgContact instance
*
* @param name name of the contact (or NULL)
* @param addr address of the contact (or NULL)
* @param ctype a valid contact type
*
* @return a new MuMsgContact instance; use mu_msg_contact_destroy
* when finished.
*/
MuMsgContact *mu_msg_contact_new (const char *name, const char *addr,
MuMsgContactType ctype);
/**
* destroy a MuMsgContact
*
* @param ct a MuMsgContact, or NULL
*/
void mu_msg_contact_destroy (MuMsgContact *ct);
/**
* macro to get the name of a contact
*
@ -90,33 +69,27 @@ void mu_msg_contact_destroy (MuMsgContact *ct);
/**
* callback function
*
*
* @param contact
* @param user_data a user provided data pointer
*
*
* @return TRUE if we should continue the foreach, FALSE otherwise
*/
typedef gboolean (*MuMsgContactForeachFunc) (MuMsgContact* contact,
gpointer user_data);
/**
* call a function for each MuMsgContact in the list
*
* @param lst a list of MuMsgContact objects
* @param func a callback function
* @param user_data user pointer, passed to the callback
*/
void mu_msg_contacts_foreach (GSList *lst,
MuMsgContactForeachFunc func,
gpointer user_data);
/**
* free a list of MuMsgContact objects
* call a function for each of the contacts in a message
*
* @param msg a valid MuMsgGMime* instance
* @param func a callback function to call for each contact; when
* the callback does not return TRUE, it won't be called again
* @param user_data a user-provide pointer that will be passed to the callback
*
* @param lst list of MuMsgContact object
*/
void mu_msg_contacts_free (GSList *lst);
void mu_msg_contact_foreach (MuMsg *msg, MuMsgContactForeachFunc func,
gpointer user_data);
#endif /*__MU_MSG_CONTACT_H__*/

View File

@ -99,7 +99,7 @@ static const MuMsgField FIELD_DATA[] = {
},
{
MU_MSG_FIELD_ID_PRIORITY,
MU_MSG_FIELD_ID_PRIO,
MU_MSG_FIELD_TYPE_INT,
"prio", "p", "P",
FLAG_GMIME | FLAG_XAPIAN_VALUE

View File

@ -34,7 +34,7 @@ enum _MuMsgFieldId {
MU_MSG_FIELD_ID_FROM,
MU_MSG_FIELD_ID_PATH,
MU_MSG_FIELD_ID_MAILDIR,
MU_MSG_FIELD_ID_PRIORITY,
MU_MSG_FIELD_ID_PRIO,
MU_MSG_FIELD_ID_SIZE,
MU_MSG_FIELD_ID_SUBJECT,
MU_MSG_FIELD_ID_TO,

View File

@ -1,375 +0,0 @@
/*
** Copyright (C) 2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 3 of the License, or
** (at your option) any later version.
**
** This program 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
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software Foundation,
** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
*/
#ifndef __MU_MSG_GMIME_H__
#define __MU_MSG_GMIME_H__
#include "mu-msg.h"
#include "mu-msg-contact.h"
#include "mu-msg-part-info.h"
G_BEGIN_DECLS
struct _MuMsgGMime;
typedef struct _MuMsgGMime MuMsgGMime;
/**
* initialize the message parsing system; this function must be called
* before doing any message parsing (ie., any of the other
* mu_msg_gmime functions). when done with the message parsing system,
* call mu_msg_gmime_uninit. Note: calling this function on an already
* initialized system has no effect
*/
void mu_msg_gmime_init (void);
/**
* uninitialize the messge parsing system that has previously been
* initialized with mu_msg_init. not calling mu_msg_uninit after
* mu_msg_init has been called will lead to memory leakage. Note:
* calling mu_msg_uninit on an uninitialized system has no
* effect
*/
void mu_msg_gmime_uninit (void);
/**
* create a new MuMsgGMime* instance which parses a message and provides
* read access to its properties; call mu_msg_destroy when done with it.
*
* @param path full path to an email message file
*
* @param mdir the maildir for this message; ie, if the path is
* ~/Maildir/foo/bar/cur/msg, the maildir would be foo/bar; you can
* pass NULL for this parameter, in which case some maildir-specific
* information is not available.
*
* @return a new MuMsgGMime instance or NULL in case of error
*/
MuMsgGMime* mu_msg_gmime_new (const char* filepath,
const char *maildir);
/**
* destroy a MuMsgGMime* instance; call this function when done with
* a MuMsgGMime
*
* @param msg a MuMsgGMime* instance or NULL
*/
void mu_msg_gmime_destroy (MuMsgGMime *msg);
/**
* get the plain text body of this message
*
* @param msg a valid MuMsgGMime* instance
*
* @return the plain text body or NULL in case of error or if there is no
* such body. the returned string should *not* be modified or freed.
* The returned data is in UTF8 or NULL.
*/
const char* mu_msg_gmime_get_body_text (MuMsgGMime *msg);
/**
* get the html body of this message
*
* @param msg a valid MuMsgGMime* instance
*
* @return the html body or NULL in case of error or if there is no
* such body. the returned string should *not* be modified or freed.
*/
const char* mu_msg_gmime_get_body_html (MuMsgGMime *msg);
/**
* get a summary of the body of this message; a summary takes up to
* the first @max_lines from the message, and replaces newlines
* etc. with single whitespace characters. This only works if there's
* a text-body for the message
*
* @param msg a valid MuMsgGMime* instance
* @param max_lines the max number of lines to summarize
*
* @return the summary of the message or NULL in case of error or if
* there is no such body. the returned string should *not* be modified
* or freed. When called multiple times, the function will always
* return the same summary, regardless of a different max_lines value.
*/
const char* mu_msg_gmime_get_summary (MuMsgGMime *msg, size_t max_lines);
struct _MuMsgGMimeAttach {
unsigned index; /* index of the attachment (names may not be unique) */
const char* name; /* name of the attachment */
size_t size; /* size in bytes, or 0 if not available */
const char* mime_type; /* the mime type */
};
typedef struct _MuMsgMimePart MuMsgMimePart;
typedef gboolean (*MuMsgMimePartForeachFunc) (MuMsgMimePart *part, gpointer data);
/**
* call a user function for each attachment found in the message. the
* function will be calle d for each attachment and as long a the
* user-function returns TRUE
*
* @param msg a valid MuMsgGMime
* @param the function to call (callback)
* @param user_data a user pointer which will be passed to the callback function
*
* @return a list of attachment
*/
void mu_msg_gmime_mime_part_foreach (MuMsgGMime* msg,
MuMsgMimePartForeachFunc func,
gpointer user_data);
/**
* save a specific attachment to some targetdir
*
* @param msg a valid MuMsgGMime instance
* @param wanted_idx index of the attachment you want to save
* @param targetdir filesystem directory to save the attachment
* @param overwrite existing files?
*
* @return TRUE if saving succeeded, FALSE otherwise
*/
gboolean
mu_msg_gmime_mime_part_save (MuMsgGMime *msg, int wanted_idx,
const char *targetdir, gboolean overwrite);
/**
* get the sender (From:) of this message
*
* @param msg a valid MuMsgGMime* instance
*
* @return the sender of this Message or NULL in case of error or if there
* is no sender. the returned string should *not* be modified or freed.
*/
const char* mu_msg_gmime_get_from (MuMsgGMime *msg);
/**
* get the recipients (To:) of this message
*
* @param msg a valid MuMsgGMime* instance
*
* @return the sender of this Message or NULL in case of error or if there
* are no recipients. the returned string should *not* be modified or freed.
*/
const char* mu_msg_gmime_get_to (MuMsgGMime *msg);
/**
* get the carbon-copy recipients (Cc:) of this message
*
* @param msg a valid MuMsgGMime* instance
*
* @return the Cc: recipients of this Message or NULL in case of error or if
* there are no such recipients. the returned string should *not* be modified
* or freed.
*/
const char* mu_msg_gmime_get_cc (MuMsgGMime *msg);
/**
* get the file system path of this message
*
* @param msg a valid MuMsgGMime* instance
*
* @return the path of this Message or NULL in case of error.
* the returned string should *not* be modified or freed.
*/
const char* mu_msg_gmime_get_path (MuMsgGMime *msg);
/**
* get the maildir this message lives in; ie, if the path is
* ~/Maildir/foo/bar/cur/msg, the maildir would be foo/bar
*
* @param msg a valid MuMsgGMime* instance
*
* @return the maildir requested or NULL in case of error. The returned
* string should *not* be modified or freed.
*/
const char* mu_msg_gmime_get_maildir (MuMsgGMime *msg);
/**
* get the subject of this message
*
* @param msg a valid MuMsgGMime* instance
*
* @return the subject of this Message or NULL in case of error or if there
* is no subject. the returned string should *not* be modified or freed.
*/
const char* mu_msg_gmime_get_subject (MuMsgGMime *msg);
/**
* get the Message-Id of this message
*
* @param msg a valid MuMsgGMime* instance
*
* @return the Message-Id of this Message (without the enclosing <>)
* or NULL in case of error or if there is none. the returned string
* should *not* be modified or freed.
*/
const char* mu_msg_gmime_get_msgid (MuMsgGMime *msg);
/**
* get any arbitrary header from this message
*
* @param msg a valid MuMsgGMime* instance
* @header the header requested
*
* @return the header requested or NULL in case of error or if there
* is no such header. the returned string should *not* be modified or freed.
*/
const char* mu_msg_gmime_get_header (MuMsgGMime *msg,
const char* header);
/**
* get the message date/time (the Date: field) as time_t, using UTC
*
* @param msg a valid MuMsgGMime* instance
*
* @return message date/time or 0 in case of error or if there
* is no such header.
*/
time_t mu_msg_gmime_get_date (MuMsgGMime *msg);
/**
* get the flags for this message
*
* @param msg valid MuMsgGMime* instance
*
* @return the fileflags as logically OR'd #Mu MsgFlags or 0 if
* there are none.
*/
MuMsgFlags mu_msg_gmime_get_flags (MuMsgGMime *msg);
/**
* get the file size in bytes of this message
*
* @param msg a valid MuMsgGMime* instance
*
* @return the filesize
*/
size_t mu_msg_gmime_get_size (MuMsgGMime *msg);
/**
* get some field value as string
*
* @param msg a valid MuMsgGmime instance
* @param field the field to retrieve; it must be a string-typed field
*
* @return a string that should not be freed
*/
const char* mu_msg_gmime_get_field_string (MuMsgGMime *msg,
const MuMsgField* field);
/**
* get some field value as string
*
* @param msg a valid MuMsgGmime instance
* @param field the field to retrieve; it must be a numeric field
*
* @return a string that should not be freed
*/
gint64 mu_msg_gmime_get_field_numeric (MuMsgGMime *msg,
const MuMsgField* field);
/**
* get the message priority for this message (MU_MSG_PRIORITY_LOW,
* MU_MSG_PRIORITY_NORMAL or MU_MSG_PRIORITY_HIGH) the X-Priority,
* X-MSMailPriority, Importance and Precedence header are checked, in
* that order. if no known or explicit priority is set,
* MU_MSG_PRIORITY_NORMAL is assumed
*
* @param msg a valid MuMsgGMime* instance
*
* @return the message priority (!= 0) or 0 in case of error
*/
MuMsgPriority mu_msg_gmime_get_priority (MuMsgGMime *msg);
/**
* get the timestamp (mtime) for the file containing this message
*
* @param msg a valid MuMsgGMime* instance
*
* @return the timestamp or 0 in case of error
*/
time_t mu_msg_gmime_get_timestamp (MuMsgGMime *msg);
/**
* get a list of contacts (MuMsgContact) for this message; you can use
* GSList functions or mu_msg_contact_list_foreach to read the items.
*
* @param msg a valid MuMsgGMime* instance
*
* @return a list of contacts for this message; use
* mu_msg_contacts_free to free it when done
*/
GSList * mu_msg_gmime_get_contacts (MuMsgGMime *msg);
/**
* call a function for each of the contacts in a message
*
* @param msg a valid MuMsgGMime* instance
* @param func a callback function to call for each contact; when
* the callback does not return TRUE, it won't be called again
* @param user_data a user-provide pointer that will be passed to the callback
*
*/
void mu_msg_gmime_contacts_foreach (MuMsgGMime *msg,
MuMsgContactForeachFunc func,
gpointer user_data);
/* /\** */
/* * get a list of message part info objects (MuMsgPartInfo) for this */
/* * message; you can use GSList functions or */
/* * mu_msg_part_info_list_foreach to read the items. */
/* * */
/* * @param msg a valid MuMsgGMime* instance */
/* * */
/* * @return a list of contacts for this message; use */
/* * mu_msg_part_infos_free to free it when done */
/* *\/ */
/* GSList *mu_msg_gmime_get_part_infos (MuMsgGMime *msg); */
/**
* call a function for each of the contacts in a message
*
* @param msg a valid MuMsgGMime* instance
* @param func a callback function to call for each contact; when
* the callback does not return TRUE, it won't be called again
* @param user_data a user-provide pointer that will be passed to the callback
*
*/
void mu_msg_gmime_msg_part_infos_foreach (MuMsgGMime *msg,
MuMsgPartInfoForeachFunc func,
gpointer user_data);
G_END_DECLS
#endif /*__MU_MSG_GIME_H__*/

View File

@ -1,5 +1,5 @@
/*
** Copyright (C) 2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 22010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by

View File

@ -1,5 +1,5 @@
/*
** Copyright (C) 2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
@ -80,11 +80,11 @@ mu_msg_iter_xapian_destroy (MuMsgIterXapian *iter)
}
MuMsgGMime*
mu_msg_iter_xapian_get_msg_gmime (MuMsgIterXapian *iter)
MuMsg*
mu_msg_iter_xapian_get_msg (MuMsgIterXapian *iter)
{
const char *path;
MuMsgGMime *msg;
MuMsg *msg;
g_return_val_if_fail (iter, NULL);
@ -94,7 +94,7 @@ mu_msg_iter_xapian_get_msg_gmime (MuMsgIterXapian *iter)
return NULL;
}
msg = mu_msg_gmime_new (path, NULL);
msg = mu_msg_new (path, NULL);
if (!msg) {
g_warning ("%s: failed to create msg object", __FUNCTION__);
return NULL;
@ -297,9 +297,8 @@ mu_msg_iter_xapian_get_flags (MuMsgIterXapian *iter)
return (MuMsgFlags) get_field_number (iter, MU_MSG_FIELD_ID_FLAGS);
}
MuMsgPriority
mu_msg_iter_xapian_get_priority (MuMsgIterXapian *iter)
MuMsgPrio
mu_msg_iter_xapian_get_prio (MuMsgIterXapian *iter)
{
return (MuMsgPriority) get_field_number (iter,
MU_MSG_FIELD_ID_PRIORITY);
return (MuMsgPrio) get_field_number (iter, MU_MSG_FIELD_ID_PRIO);
}

View File

@ -21,7 +21,6 @@
#define __MU_MSG_ITER_XAPIAN_H__
#include "mu-msg.h"
#include "mu-msg-gmime.h"
G_BEGIN_DECLS
@ -60,7 +59,7 @@ void mu_msg_iter_xapian_destroy (MuMsgIterXapian *iter);
/**
* get the corresponding GMime message for this iter; this requires
* get the corresponding MuMsg for this iter; this requires
* the corresponding message file to be present at the expected place
*
* @param iter a valid MuMsgIterXapian instance
@ -68,7 +67,7 @@ void mu_msg_iter_xapian_destroy (MuMsgIterXapian *iter);
* @return a MuMsgGMime instance, or NULL in case of error. Use
* mu_msg_gmime_destroy when the instance is no longer needed
*/
MuMsgGMime* mu_msg_iter_xapian_get_msg_gmime (MuMsgIterXapian *iter);
MuMsg* mu_msg_iter_xapian_get_msg (MuMsgIterXapian *iter);
/**
* get the document id for the current message
@ -169,9 +168,9 @@ MuMsgFlags mu_msg_iter_xapian_get_flags (MuMsgIterXapian *iter);
*
* @param iter a valid MuMsgIterXapian iterator
*
* @return the message priority, or MU_MSG_PRIORITY_NONE
* @return the message priority, or MU_MSG_PRIO_NONE
*/
MuMsgPriority mu_msg_iter_xapian_get_priority (MuMsgIterXapian *iter);
MuMsgPrio mu_msg_iter_xapian_get_prio (MuMsgIterXapian *iter);
/**

View File

@ -1,70 +0,0 @@
/*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify it
** under the terms of the GNU General Public License as published by the
** Free Software Foundation; either version 3, or (at your option) any
** later version.
**
** This program 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
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software Foundation,
** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /*HAVE_CONFIG_H*/
#include "mu-msg-part-info.h"
MuMsgPartInfo*
mu_msg_part_info_new (void)
{
return g_slice_new0 (MuMsgPartInfo);
}
void
mu_msg_part_info_destroy (MuMsgPartInfo *pi)
{
if (!pi)
return;
if (pi->own_members) {
g_free (pi->content_id);
g_free (pi->type);
g_free (pi->subtype);
/* g_free (pi->content_type); */
g_free (pi->file_name);
g_free (pi->disposition);
}
g_slice_free (MuMsgPartInfo, pi);
}
void
mu_msg_part_infos_foreach (GSList *lst,
MuMsgPartInfoForeachFunc func,
gpointer user_data)
{
for (; lst ; lst = g_slist_next (lst))
func((MuMsgPartInfo*)lst->data, user_data);
}
void
mu_msg_part_infos_free (GSList *lst)
{
g_slist_foreach (lst, (GFunc)mu_msg_part_info_destroy, NULL);
g_slist_free (lst);
}

179
src/mu-msg-part.c Normal file
View File

@ -0,0 +1,179 @@
/*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify it
** under the terms of the GNU General Public License as published by the
** Free Software Foundation; either version 3, or (at your option) any
** later version.
**
** This program 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
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software Foundation,
** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /*HAVE_CONFIG_H*/
#include <string.h>
#include <unistd.h>
#include "mu-util.h"
#include "mu-msg-priv.h"
#include "mu-msg-part.h"
struct _PartData {
unsigned _idx;
MuMsgPartForeachFunc _func;
gpointer _user_data;
};
typedef struct _PartData PartData;
static void
part_foreach_cb (GMimeObject *parent, GMimeObject *part, PartData *pdata)
{
GMimeContentType *ct;
MuMsgPart pi;
memset (&pi, 0, sizeof pi);
pi.index = pdata->_idx++;
pi.content_id = (char*)g_mime_object_get_content_id (part);
ct = g_mime_object_get_content_type (part);
if (GMIME_IS_CONTENT_TYPE(ct)) {
pi.type = (char*)g_mime_content_type_get_media_type (ct);
pi.subtype = (char*)g_mime_content_type_get_media_subtype (ct);
}
if (GMIME_IS_PART(part)) {
pi.disposition = (char*)g_mime_object_get_disposition (part);
pi.file_name = (char*)g_mime_part_get_filename (GMIME_PART(part));
}
pdata->_func(&pi, pdata->_user_data);
}
void
mu_msg_msg_part_foreach (MuMsg *msg,
MuMsgPartForeachFunc func,
gpointer user_data)
{
PartData pdata;
g_return_if_fail (msg);
g_return_if_fail (GMIME_IS_OBJECT(msg->_mime_msg));
pdata._idx = 0;
pdata._func = func;
pdata._user_data = user_data;
g_mime_message_foreach (msg->_mime_msg,
(GMimeObjectForeachFunc)part_foreach_cb,
&pdata);
}
struct _SavePartData {
guint idx, wanted_idx;
const gchar* targetdir;
gboolean overwrite;
gboolean stream;
gboolean result;
};
typedef struct _SavePartData SavePartData;
static gboolean
save_part (GMimeObject *part, const char *filename,
const char *targetdir, gboolean overwrite)
{
int fd, rv;
GMimeDataWrapper *wrapper;
GMimeStream *stream;
rv = TRUE;
fd = mu_util_create_writeable_fd (filename, targetdir,
overwrite);
if (fd == -1) {
g_warning ("error saving file %s%s %s",
filename, errno != 0 ? ":" : "",
errno != 0 ? strerror(errno) : "");
return FALSE;
}
stream = g_mime_stream_fs_new (fd);
if (!stream) {
g_warning ("%s: failed to create stream", __FUNCTION__);
close (fd);
return FALSE;
}
g_mime_stream_fs_set_owner (GMIME_STREAM_FS(stream),
TRUE); /* GMimeStream will close fd */
wrapper = g_mime_part_get_content_object (GMIME_PART(part));
if (!wrapper) {
g_object_unref (G_OBJECT(stream));
g_warning ("%s: failed to create wrapper", __FUNCTION__);
return FALSE;
}
rv = g_mime_data_wrapper_write_to_stream (wrapper, stream);
g_object_unref (G_OBJECT(stream));
return rv == -1 ? FALSE : TRUE;
}
static void
part_foreach_save_cb (GMimeObject *parent, GMimeObject *part,
SavePartData *spd)
{
const gchar* filename;
/* did we find the right part yet? */
if (spd->result || spd->wanted_idx != spd->idx++)
return;
if (!GMIME_IS_PART(part))
return;
filename = g_mime_part_get_filename (GMIME_PART(part));
if (filename) {
spd->result = save_part (part, filename,
spd->targetdir,
spd->overwrite);
} else
spd->result = FALSE;
}
gboolean
mu_msg_mime_part_save (MuMsg *msg, int wanted_idx,
const char *targetdir, gboolean overwrite)
{
SavePartData spd;
spd.idx = 0;
spd.wanted_idx = wanted_idx;
spd.targetdir = targetdir;
spd.overwrite = overwrite;
spd.stream = FALSE;
spd.result = FALSE;
g_mime_message_foreach (msg->_mime_msg,
(GMimeObjectForeachFunc)part_foreach_save_cb,
&spd);
return spd.result;
}

View File

@ -17,12 +17,12 @@
**
*/
#ifndef __MU_MSG_PART_INFO_H__
#define __MU_MSG_PART_INFO_H__
#ifndef __MU_MSG_PART_H__
#define __MU_MSG_PART_H__
#include <glib.h>
struct _MuMsgPartInfo {
struct _MuMsgPart {
/* index of this message */
unsigned index;
@ -40,7 +40,7 @@ struct _MuMsgPartInfo {
char *file_name;
/* usually, "attachment" or "inline"; use
* mu_msg_part_info_is_(attachment|inline)
* mu_msg_part_is_(attachment|inline)
* to test */
char *disposition;
@ -49,75 +49,45 @@ struct _MuMsgPartInfo {
gpointer data; /* opaque data */
/* if TRUE, mu_msg_part_info_destroy will free the member vars
/* if TRUE, mu_msg_part_destroy will free the member vars
* as well*/
gboolean own_members;
};
typedef struct _MuMsgPartInfo MuMsgPartInfo;
/**
* create a new MuMsgPartInfo instance; this just allocates the
* memory, you'll have to fill it yourself
*
*
* @return a new MuMsgPartInfo instance; use mu_msg_part_info_destroy
* when finished.
*/
MuMsgPartInfo *mu_msg_part_info_new (void);
/**
* destroy a MuMsgPartInfo object
*
* @param ct a MuMsgPartInfo object, or NULL
*/
void mu_msg_part_info_destroy (MuMsgPartInfo *pinfo);
typedef struct _MuMsgPart MuMsgPart;
/**
* macro to get the file name for this mime-part
*
* @param pi a MuMsgPartInfo instance
* @param pi a MuMsgPart instance
*
* @return the file name
*/
#define mu_msg_part_info_file_name(pi) ((pi)->file_name)
#define mu_msg_part_file_name(pi) ((pi)->file_name)
/**
* macro to get the file name for this mime-part
*
* @param pi a MuMsgPartInfo instance
* @param pi a MuMsgPart instance
*
* @return the file name
*/
#define mu_msg_part_content_type(pi) ((pi)->content_type)
/**
* callback function
*
* @param a msg part info object
* @param user_data a user provided data pointer
*
*/
typedef void (*MuMsgPartInfoForeachFunc) (MuMsgPartInfo* part,
gpointer user_data);
typedef void (*MuMsgPartForeachFunc) (MuMsgPart *part, gpointer data);
/**
* call a function for each MuMsgPartInfo (MIME-part) in the list
* call a function for each of the contacts in a message
*
* @param msg a valid MuMsg* instance
* @param func a callback function to call for each contact; when
* the callback does not return TRUE, it won't be called again
* @param user_data a user-provide pointer that will be passed to the callback
*
* @param lst a list of MuMsgPartInfo objects
* @param func a callback function
* @param user_data user pointer, passed to the callback
*/
void mu_msg_part_infos_foreach (GSList *lst,
MuMsgPartInfoForeachFunc func,
gpointer user_data);
void mu_msg_msg_part_foreach (MuMsg *msg,
MuMsgPartForeachFunc func,
gpointer user_data);
/**
* free a list of MuMsgPartInfo objects
*
* @param lst list of MuMsgPartInfo object
*/
void mu_msg_part_infos_free (GSList *lst);
#endif /*__MU_MSG_PART_INFO_H__*/
#endif /*__MU_MSG_PART_H__*/

32
src/mu-msg-prio.h Normal file
View File

@ -0,0 +1,32 @@
/*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 3 of the License, or
** (at your option) any later version.
**
** This program 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
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software Foundation,
** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
*/
#ifndef __MU_MSG_PRIO_H__
#define __MU_MSG_PRIO_H__
enum _MuMsgPrio {
MU_MSG_PRIO_NONE = 0,
MU_MSG_PRIO_LOW = 1,
MU_MSG_PRIO_NORMAL = 2,
MU_MSG_PRIO_HIGH = 3
};
typedef enum _MuMsgPrio MuMsgPrio;
#endif /*__MU_MSG_PRIO_H__*/

60
src/mu-msg-priv.h Normal file
View File

@ -0,0 +1,60 @@
/*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 3 of the License, or
** (at your option) any later version.
**
** This program 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
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software Foundation,
** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
*/
#ifndef __MU_MSG_PRIV_H__
#define __MU_MSG_PRIV_H__
#include <gmime/gmime.h>
#include <stdlib.h>
#include "mu-msg.h"
/* we put the the MuMsg definition in this separate -priv file, so we
* can split the mu_msg implementations over separate files */
enum _StringFields {
HTML_FIELD = 0, /* body as HTML */
TEXT_FIELD, /* body as plain text */
SUMMARY_FIELD, /* body summary */
TO_FIELD, /* To: */
CC_FIELD, /* Cc: */
PATH_FIELD, /* full path */
MDIR_FIELD, /* the maildir */
FLAGS_FIELD_STR, /* message flags */
FIELD_NUM
};
typedef enum _StringFields StringFields;
struct _MuMsg {
GMimeMessage *_mime_msg;
MuMsgFlags _flags;
char* _fields[FIELD_NUM];
size_t _size;
time_t _timestamp;
MuMsgPrio _prio;
};
#endif /*__MU_MSG_PRIV_H__*/

34
src/mu-msg-status.h Normal file
View File

@ -0,0 +1,34 @@
/*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 3 of the License, or
** (at your option) any later version.
**
** This program 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
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software Foundation,
** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
*/
#ifndef __MU_MSG_STATUS_H__
#define __MU_MSG_STATUS_H__
/* what kind of message is this; use by the indexer */
enum _MuMsgStatus {
MU_MSG_STATUS_NEW, /* message is new */
MU_MSG_STATUS_UPDATE, /* message is to be updated */
MU_MSG_STATUS_CLEANUP, /* message is to be cleaned up from db */
MU_MSG_STATUS_CLEANED_UP, /* message has been cleaned up from db */
MU_MSG_STATUS_EXISTS, /* message exists (will not be cleaned up) */
MU_MSG_STATUS_UPTODATE /* message is up-to-date */
};
typedef enum _MuMsgStatus MuMsgStatus;
#endif /*__MU_MSG_STATUS_H__*/

View File

@ -85,18 +85,18 @@ mu_msg_str_flags (MuMsgFlags flags)
}
const char*
mu_msg_str_prio (MuMsgPriority prio)
mu_msg_str_prio (MuMsgPrio prio)
{
switch (prio) {
case MU_MSG_PRIORITY_LOW:
case MU_MSG_PRIO_LOW:
return "low";
case MU_MSG_PRIORITY_NONE:
case MU_MSG_PRIORITY_NORMAL:
case MU_MSG_PRIO_NONE:
case MU_MSG_PRIO_NORMAL:
return "normal";
case MU_MSG_PRIORITY_HIGH:
case MU_MSG_PRIO_HIGH:
return "high";
default:

View File

@ -89,7 +89,7 @@ char* mu_msg_str_flags (MuMsgFlags flags) G_GNUC_WARN_UNUSED_RESULT;
* @return a string representation of the priority; see above
* for what to do with it, or NULL in case of error
*/
const char* mu_msg_str_prio (MuMsgPriority prio) G_GNUC_CONST;
const char* mu_msg_str_prio (MuMsgPrio prio) G_GNUC_CONST;
#endif /*__MU_MSG_STR_H__*/

View File

@ -27,42 +27,14 @@
#include <ctype.h>
#include "mu-util.h"
#include "mu-msg-gmime.h"
enum _StringFields {
HTML_FIELD = 0, /* body as HTML */
TEXT_FIELD, /* body as plain text */
SUMMARY_FIELD, /* body summary */
TO_FIELD, /* To: */
CC_FIELD, /* Cc: */
PATH_FIELD, /* full path */
MDIR_FIELD, /* the maildir */
FLAGS_FIELD_STR, /* message flags */
FIELD_NUM
};
typedef enum _StringFields StringFields;
struct _MuMsgGMime {
GMimeMessage *_mime_msg;
MuMsgFlags _flags;
char* _fields[FIELD_NUM];
size_t _size;
time_t _timestamp;
MuMsgPriority _prio;
};
#include "mu-msg-priv.h" /* include before mu-msg.h */
#include "mu-msg.h"
void
mu_msg_gmime_destroy (MuMsgGMime *msg)
mu_msg_destroy (MuMsg *msg)
{
int i;
@ -77,12 +49,12 @@ mu_msg_gmime_destroy (MuMsgGMime *msg)
for (i = 0; i != FIELD_NUM; ++i)
g_free (msg->_fields[i]);
g_slice_free (MuMsgGMime, msg);
g_slice_free (MuMsg, msg);
}
static gboolean
init_file_metadata (MuMsgGMime* msg, const char* path, const gchar* mdir)
init_file_metadata (MuMsg* msg, const char* path, const gchar* mdir)
{
struct stat statbuf;
@ -117,16 +89,16 @@ init_file_metadata (MuMsgGMime* msg, const char* path, const gchar* mdir)
static gboolean
init_mime_msg (MuMsgGMime *msg)
init_mime_msg (MuMsg *msg)
{
FILE *file;
GMimeStream *stream;
GMimeParser *parser;
file = fopen (mu_msg_gmime_get_path(msg), "r");
file = fopen (mu_msg_get_path(msg), "r");
if (!file) {
g_warning ("%s:cannot open %s: %s",
__FUNCTION__, mu_msg_gmime_get_path(msg),
__FUNCTION__, mu_msg_get_path(msg),
strerror (errno));
return FALSE;
}
@ -156,24 +128,24 @@ init_mime_msg (MuMsgGMime *msg)
}
MuMsgGMime*
mu_msg_gmime_new (const char* filepath, const gchar* mdir)
MuMsg*
mu_msg_new (const char* filepath, const gchar* mdir)
{
MuMsgGMime *msg;
MuMsg *msg;
g_return_val_if_fail (filepath, NULL);
msg = g_slice_new0 (MuMsgGMime);
msg = g_slice_new0 (MuMsg);
if (!msg)
return NULL;
if (!init_file_metadata(msg, filepath, mdir)) {
mu_msg_gmime_destroy (msg);
mu_msg_destroy (msg);
return NULL;
}
if (!init_mime_msg(msg)) {
mu_msg_gmime_destroy (msg);
mu_msg_destroy (msg);
return NULL;
}
@ -182,7 +154,7 @@ mu_msg_gmime_new (const char* filepath, const gchar* mdir)
const char*
mu_msg_gmime_get_path (MuMsgGMime *msg)
mu_msg_get_path (MuMsg *msg)
{
g_return_val_if_fail (msg, NULL);
@ -191,7 +163,7 @@ mu_msg_gmime_get_path (MuMsgGMime *msg)
const char*
mu_msg_gmime_get_subject (MuMsgGMime *msg)
mu_msg_get_subject (MuMsg *msg)
{
g_return_val_if_fail (msg, NULL);
@ -199,7 +171,7 @@ mu_msg_gmime_get_subject (MuMsgGMime *msg)
}
const char*
mu_msg_gmime_get_msgid (MuMsgGMime *msg)
mu_msg_get_msgid (MuMsg *msg)
{
g_return_val_if_fail (msg, NULL);
@ -208,7 +180,7 @@ mu_msg_gmime_get_msgid (MuMsgGMime *msg)
const char*
mu_msg_gmime_get_maildir (MuMsgGMime *msg)
mu_msg_get_maildir (MuMsg *msg)
{
g_return_val_if_fail (msg, NULL);
@ -218,7 +190,7 @@ mu_msg_gmime_get_maildir (MuMsgGMime *msg)
const char*
mu_msg_gmime_get_from (MuMsgGMime *msg)
mu_msg_get_from (MuMsg *msg)
{
g_return_val_if_fail (msg, NULL);
@ -227,7 +199,7 @@ mu_msg_gmime_get_from (MuMsgGMime *msg)
static const char*
get_recipient (MuMsgGMime *msg, GMimeRecipientType rtype, StringFields field)
get_recipient (MuMsg *msg, GMimeRecipientType rtype, StringFields field)
{
/* can only be set once */
if (!msg->_fields[field]) {
@ -250,14 +222,14 @@ get_recipient (MuMsgGMime *msg, GMimeRecipientType rtype, StringFields field)
const char*
mu_msg_gmime_get_to (MuMsgGMime *msg)
mu_msg_get_to (MuMsg *msg)
{
g_return_val_if_fail (msg, NULL);
return get_recipient (msg, GMIME_RECIPIENT_TYPE_TO, TO_FIELD);
}
const char*
mu_msg_gmime_get_cc (MuMsgGMime *msg)
mu_msg_get_cc (MuMsg *msg)
{
g_return_val_if_fail (msg, NULL);
return get_recipient (msg, GMIME_RECIPIENT_TYPE_CC, CC_FIELD);
@ -265,7 +237,7 @@ mu_msg_gmime_get_cc (MuMsgGMime *msg)
time_t
mu_msg_gmime_get_date (MuMsgGMime *msg)
mu_msg_get_date (MuMsg *msg)
{
time_t t;
@ -311,7 +283,7 @@ msg_cflags_cb (GMimeObject *parent, GMimeObject *part, MuMsgFlags *flags)
static MuMsgFlags
get_content_flags (MuMsgGMime *msg)
get_content_flags (MuMsg *msg)
{
GMimeContentType *ctype;
MuMsgFlags flags = 0;
@ -349,13 +321,13 @@ get_content_flags (MuMsgGMime *msg)
MuMsgFlags
mu_msg_gmime_get_flags (MuMsgGMime *msg)
mu_msg_get_flags (MuMsg *msg)
{
g_return_val_if_fail (msg, MU_MSG_FLAG_UNKNOWN);
if (msg->_flags == MU_MSG_FLAG_UNKNOWN) {
msg->_flags = 0;
msg->_flags = mu_msg_flags_from_file (mu_msg_gmime_get_path(msg));
msg->_flags = mu_msg_flags_from_file (mu_msg_get_path(msg));
msg->_flags |= get_content_flags (msg);
}
@ -364,7 +336,7 @@ mu_msg_gmime_get_flags (MuMsgGMime *msg)
size_t
mu_msg_gmime_get_size (MuMsgGMime *msg)
mu_msg_get_size (MuMsg *msg)
{
g_return_val_if_fail (msg, -1);
@ -385,7 +357,7 @@ to_lower (char *s)
static char*
get_prio_str (MuMsgGMime *msg)
get_prio_str (MuMsg *msg)
{
const char *str;
GMimeObject *obj;
@ -406,26 +378,26 @@ get_prio_str (MuMsgGMime *msg)
}
static MuMsgPriority
static MuMsgPrio
parse_prio_str (const char* priostr)
{
int i;
struct {
const char* _str;
MuMsgPriority _prio;
MuMsgPrio _prio;
} str_prio[] = {
{ "high", MU_MSG_PRIORITY_HIGH },
{ "1", MU_MSG_PRIORITY_HIGH },
{ "2", MU_MSG_PRIORITY_HIGH },
{ "high", MU_MSG_PRIO_HIGH },
{ "1", MU_MSG_PRIO_HIGH },
{ "2", MU_MSG_PRIO_HIGH },
{ "normal", MU_MSG_PRIORITY_NORMAL },
{ "3", MU_MSG_PRIORITY_NORMAL },
{ "normal", MU_MSG_PRIO_NORMAL },
{ "3", MU_MSG_PRIO_NORMAL },
{ "low", MU_MSG_PRIORITY_LOW },
{ "list", MU_MSG_PRIORITY_LOW },
{ "bulk", MU_MSG_PRIORITY_LOW },
{ "4", MU_MSG_PRIORITY_LOW },
{ "5", MU_MSG_PRIORITY_LOW }
{ "low", MU_MSG_PRIO_LOW },
{ "list", MU_MSG_PRIO_LOW },
{ "bulk", MU_MSG_PRIO_LOW },
{ "4", MU_MSG_PRIO_LOW },
{ "5", MU_MSG_PRIO_LOW }
};
for (i = 0; i != G_N_ELEMENTS(str_prio); ++i)
@ -433,24 +405,24 @@ parse_prio_str (const char* priostr)
return str_prio[i]._prio;
/* e.g., last-fm uses 'fm-user'... as precedence */
return MU_MSG_PRIORITY_NORMAL;
return MU_MSG_PRIO_NORMAL;
}
MuMsgPriority
mu_msg_gmime_get_priority (MuMsgGMime *msg)
MuMsgPrio
mu_msg_get_prio (MuMsg *msg)
{
char* priostr;
MuMsgPriority prio;
MuMsgPrio prio;
g_return_val_if_fail (msg, 0);
if (msg->_prio != MU_MSG_PRIORITY_NONE)
if (msg->_prio != MU_MSG_PRIO_NONE)
return msg->_prio;
priostr = get_prio_str (msg);
if (!priostr)
return MU_MSG_PRIORITY_NORMAL;
return MU_MSG_PRIO_NORMAL;
prio = parse_prio_str (priostr);
@ -461,7 +433,7 @@ mu_msg_gmime_get_priority (MuMsgGMime *msg)
const char*
mu_msg_gmime_get_header (MuMsgGMime *msg, const char* header)
mu_msg_get_header (MuMsg *msg, const char* header)
{
g_return_val_if_fail (msg, NULL);
g_return_val_if_fail (header, NULL);
@ -472,7 +444,7 @@ mu_msg_gmime_get_header (MuMsgGMime *msg, const char* header)
time_t
mu_msg_gmime_get_timestamp (MuMsgGMime *msg)
mu_msg_get_timestamp (MuMsg *msg)
{
g_return_val_if_fail (msg, 0);
@ -666,7 +638,7 @@ cleanup:
static char*
get_body (MuMsgGMime *msg, gboolean want_html)
get_body (MuMsg *msg, gboolean want_html)
{
GetBodyData data;
@ -690,7 +662,7 @@ get_body (MuMsgGMime *msg, gboolean want_html)
}
const char*
mu_msg_gmime_get_body_html (MuMsgGMime *msg)
mu_msg_get_body_html (MuMsg *msg)
{
g_return_val_if_fail (msg, NULL);
@ -702,7 +674,7 @@ mu_msg_gmime_get_body_html (MuMsgGMime *msg)
const char*
mu_msg_gmime_get_body_text (MuMsgGMime *msg)
mu_msg_get_body_text (MuMsg *msg)
{
g_return_val_if_fail (msg, NULL);
@ -751,7 +723,7 @@ summarize (const char* str, size_t max_lines)
const char*
mu_msg_gmime_get_summary (MuMsgGMime *msg, size_t max_lines)
mu_msg_get_summary (MuMsg *msg, size_t max_lines)
{
const char *body;
@ -763,7 +735,7 @@ mu_msg_gmime_get_summary (MuMsgGMime *msg, size_t max_lines)
return msg->_fields[SUMMARY_FIELD];
/* nope; calculate it */
body = mu_msg_gmime_get_body_text (msg);
body = mu_msg_get_body_text (msg);
if (!body)
return NULL; /* there was no text body */
@ -772,7 +744,7 @@ mu_msg_gmime_get_summary (MuMsgGMime *msg, size_t max_lines)
const char*
mu_msg_gmime_get_field_string (MuMsgGMime *msg, const MuMsgField* field)
mu_msg_get_field_string (MuMsg *msg, const MuMsgField* field)
{
MuMsgFieldId id;
@ -781,22 +753,22 @@ mu_msg_gmime_get_field_string (MuMsgGMime *msg, const MuMsgField* field)
g_return_val_if_fail (id != MU_MSG_FIELD_ID_NONE, NULL);
switch (id) {
case MU_MSG_FIELD_ID_BODY_TEXT: return mu_msg_gmime_get_body_text (msg);
case MU_MSG_FIELD_ID_BODY_HTML: return mu_msg_gmime_get_body_html (msg);
case MU_MSG_FIELD_ID_CC: return mu_msg_gmime_get_cc (msg);
case MU_MSG_FIELD_ID_FROM: return mu_msg_gmime_get_from (msg);
case MU_MSG_FIELD_ID_PATH: return mu_msg_gmime_get_path (msg);
case MU_MSG_FIELD_ID_SUBJECT: return mu_msg_gmime_get_subject (msg);
case MU_MSG_FIELD_ID_TO: return mu_msg_gmime_get_to (msg);
case MU_MSG_FIELD_ID_MSGID: return mu_msg_gmime_get_msgid (msg);
case MU_MSG_FIELD_ID_MAILDIR: return mu_msg_gmime_get_maildir (msg);
case MU_MSG_FIELD_ID_BODY_TEXT: return mu_msg_get_body_text (msg);
case MU_MSG_FIELD_ID_BODY_HTML: return mu_msg_get_body_html (msg);
case MU_MSG_FIELD_ID_CC: return mu_msg_get_cc (msg);
case MU_MSG_FIELD_ID_FROM: return mu_msg_get_from (msg);
case MU_MSG_FIELD_ID_PATH: return mu_msg_get_path (msg);
case MU_MSG_FIELD_ID_SUBJECT: return mu_msg_get_subject (msg);
case MU_MSG_FIELD_ID_TO: return mu_msg_get_to (msg);
case MU_MSG_FIELD_ID_MSGID: return mu_msg_get_msgid (msg);
case MU_MSG_FIELD_ID_MAILDIR: return mu_msg_get_maildir (msg);
default:
g_return_val_if_reached (NULL);
}
}
gint64
mu_msg_gmime_get_field_numeric (MuMsgGMime *msg, const MuMsgField* field)
mu_msg_get_field_numeric (MuMsg *msg, const MuMsgField* field)
{
MuMsgFieldId id;
@ -806,13 +778,13 @@ mu_msg_gmime_get_field_numeric (MuMsgGMime *msg, const MuMsgField* field)
switch (id) {
case MU_MSG_FIELD_ID_DATE:
return mu_msg_gmime_get_date(msg);
return mu_msg_get_date(msg);
case MU_MSG_FIELD_ID_FLAGS:
return mu_msg_gmime_get_flags(msg);
case MU_MSG_FIELD_ID_PRIORITY:
return mu_msg_gmime_get_priority(msg);
return mu_msg_get_flags(msg);
case MU_MSG_FIELD_ID_PRIO:
return mu_msg_get_prio(msg);
case MU_MSG_FIELD_ID_SIZE:
return mu_msg_gmime_get_size(msg);
return mu_msg_get_size(msg);
default:
g_warning ("%s: %u", __FUNCTION__, (guint)id);
g_return_val_if_reached (0);
@ -820,139 +792,12 @@ mu_msg_gmime_get_field_numeric (MuMsgGMime *msg, const MuMsgField* field)
}
static gboolean
fill_contact (MuMsgContact *contact, InternetAddress *addr,
MuMsgContactType ctype)
{
if (!addr)
return FALSE;
contact->name = (char*)internet_address_get_name (addr);
contact->type = ctype;
/* we only support internet addresses;
* if we don't check, g_mime hits an assert
*/
contact->address = (char*)internet_address_mailbox_get_addr
(INTERNET_ADDRESS_MAILBOX(addr));
return TRUE;
}
static void
address_list_foreach (InternetAddressList *addrlist,
MuMsgContactType ctype,
MuMsgContactForeachFunc func,
gpointer user_data)
{
int i;
if (!addrlist)
return;
for (i = 0; i != internet_address_list_length(addrlist); ++i) {
MuMsgContact contact;
if (!fill_contact(&contact,
internet_address_list_get_address (addrlist, i),
ctype)) {
MU_WRITE_LOG ("ignoring contact");
continue;
}
if (!(func)(&contact, user_data))
break;
}
return;
}
static void
get_contacts_from (MuMsgGMime *msg, MuMsgContactForeachFunc func,
gpointer user_data)
{
InternetAddressList *lst;
/* we go through this whole excercise of trying to get a *list*
* of 'From:' address (usually there is only one...), because
* internet_address_parse_string has the nice side-effect of
* splitting in names and addresses for us */
lst = internet_address_list_parse_string (
g_mime_message_get_sender (msg->_mime_msg));
if (lst) {
address_list_foreach (lst, MU_MSG_CONTACT_TYPE_FROM,
func, user_data);
g_object_unref (G_OBJECT(lst));
}
}
void
mu_msg_gmime_contacts_foreach (MuMsgGMime *msg, MuMsgContactForeachFunc func,
gpointer user_data)
{
int i;
struct {
GMimeRecipientType _gmime_type;
MuMsgContactType _type;
} ctypes[] = {
{GMIME_RECIPIENT_TYPE_TO, MU_MSG_CONTACT_TYPE_TO},
{GMIME_RECIPIENT_TYPE_CC, MU_MSG_CONTACT_TYPE_CC},
{GMIME_RECIPIENT_TYPE_BCC, MU_MSG_CONTACT_TYPE_BCC},
};
g_return_if_fail (func && msg);
/* first, get the from address(es) */
get_contacts_from (msg, func, user_data);
/* get to, cc, bcc */
for (i = 0; i != G_N_ELEMENTS(ctypes); ++i) {
InternetAddressList *addrlist;
addrlist = g_mime_message_get_recipients (msg->_mime_msg,
ctypes[i]._gmime_type);
address_list_foreach (addrlist, ctypes[i]._type, func, user_data);
}
}
static gboolean
each_contact (MuMsgContact *contact, GSList **lst)
{
MuMsgContact *ct;
ct = mu_msg_contact_new (mu_msg_contact_name(contact),
mu_msg_contact_address (contact),
mu_msg_contact_type (contact));
*lst = g_slist_append (*lst, ct);
return TRUE;
}
GSList *
mu_msg_gmime_get_contacts (MuMsgGMime *msg)
{
GSList *contacts;
g_return_val_if_fail (msg, NULL);
contacts = NULL;
mu_msg_gmime_contacts_foreach (msg,
(MuMsgContactForeachFunc)each_contact,
&contacts);
return contacts;
}
static gboolean _initialized = FALSE;
void
mu_msg_gmime_init (void)
mu_msg_init (void)
{
if (!_initialized) {
g_mime_init(0);
@ -963,7 +808,7 @@ mu_msg_gmime_init (void)
void
mu_msg_gmime_uninit (void)
mu_msg_uninit (void)
{
if (_initialized) {
g_mime_shutdown();
@ -972,153 +817,3 @@ mu_msg_gmime_uninit (void)
}
}
struct _PartData {
unsigned _idx;
MuMsgPartInfoForeachFunc _func;
gpointer _user_data;
};
typedef struct _PartData PartData;
static void
part_foreach_cb (GMimeObject *parent, GMimeObject *part, PartData *pdata)
{
GMimeContentType *ct;
MuMsgPartInfo pi;
memset (&pi, 0, sizeof pi);
pi.index = pdata->_idx++;
pi.content_id = (char*)g_mime_object_get_content_id (part);
ct = g_mime_object_get_content_type (part);
if (GMIME_IS_CONTENT_TYPE(ct)) {
pi.type = (char*)g_mime_content_type_get_media_type (ct);
pi.subtype = (char*)g_mime_content_type_get_media_subtype (ct);
}
if (GMIME_IS_PART(part)) {
pi.disposition = (char*)g_mime_object_get_disposition (part);
pi.file_name = (char*)g_mime_part_get_filename (GMIME_PART(part));
}
pdata->_func(&pi, pdata->_user_data);
}
void
mu_msg_gmime_msg_part_infos_foreach (MuMsgGMime *msg,
MuMsgPartInfoForeachFunc func,
gpointer user_data)
{
PartData pdata;
g_return_if_fail (msg);
g_return_if_fail (GMIME_IS_OBJECT(msg->_mime_msg));
pdata._idx = 0;
pdata._func = func;
pdata._user_data = user_data;
g_mime_message_foreach (msg->_mime_msg,
(GMimeObjectForeachFunc)part_foreach_cb,
&pdata);
}
struct _SavePartData {
guint idx, wanted_idx;
const gchar* targetdir;
gboolean overwrite;
gboolean stream;
gboolean result;
};
typedef struct _SavePartData SavePartData;
static gboolean
save_part (GMimeObject *part, const char *filename,
const char *targetdir, gboolean overwrite)
{
int fd, rv;
GMimeDataWrapper *wrapper;
GMimeStream *stream;
rv = TRUE;
fd = mu_util_create_writeable_fd (filename, targetdir,
overwrite);
if (fd == -1) {
g_warning ("error saving file %s%s %s",
filename, errno != 0 ? ":" : "",
errno != 0 ? strerror(errno) : "");
return FALSE;
}
stream = g_mime_stream_fs_new (fd);
if (!stream) {
g_warning ("%s: failed to create stream", __FUNCTION__);
close (fd);
return FALSE;
}
g_mime_stream_fs_set_owner (GMIME_STREAM_FS(stream),
TRUE); /* GMimeStream will close fd */
wrapper = g_mime_part_get_content_object (GMIME_PART(part));
if (!wrapper) {
g_object_unref (G_OBJECT(stream));
g_warning ("%s: failed to create wrapper", __FUNCTION__);
return FALSE;
}
rv = g_mime_data_wrapper_write_to_stream (wrapper, stream);
g_object_unref (G_OBJECT(rv));
return rv == -1 ? FALSE : TRUE;
}
static void
part_foreach_save_cb (GMimeObject *parent, GMimeObject *part,
SavePartData *spd)
{
const gchar* filename;
/* did we find the right part yet? */
if (spd->result || spd->wanted_idx != spd->idx++)
return;
if (!GMIME_IS_PART(part))
return;
filename = g_mime_part_get_filename (GMIME_PART(part));
if (filename) {
spd->result = save_part (part, filename,
spd->targetdir,
spd->overwrite);
} else
spd->result = FALSE;
}
gboolean
mu_msg_gmime_mime_part_save (MuMsgGMime *msg, int wanted_idx,
const char *targetdir, gboolean overwrite)
{
SavePartData spd;
spd.idx = 0;
spd.wanted_idx = wanted_idx;
spd.targetdir = targetdir;
spd.overwrite = overwrite;
spd.stream = FALSE;
spd.result = FALSE;
g_mime_message_foreach (msg->_mime_msg,
(GMimeObjectForeachFunc)part_foreach_save_cb,
&spd);
return spd.result;
}

View File

@ -22,25 +22,280 @@
#include "mu-msg-flags.h"
#include "mu-msg-fields.h"
#include "mu-msg-status.h"
#include "mu-msg-prio.h"
/* what kind of message is this; use by the indexer */
enum _MuMsgStatus {
MU_MSG_STATUS_NEW, /* message is new */
MU_MSG_STATUS_UPDATE, /* message is to be updated */
MU_MSG_STATUS_CLEANUP, /* message is to be cleaned up from db */
MU_MSG_STATUS_CLEANED_UP, /* message has been cleaned up from db */
MU_MSG_STATUS_EXISTS, /* message exists (will not be cleaned up) */
MU_MSG_STATUS_UPTODATE /* message is up-to-date */
};
typedef enum _MuMsgStatus MuMsgStatus;
G_BEGIN_DECLS
enum _MuMsgPriority {
MU_MSG_PRIORITY_NONE = 0,
struct _MuMsg;
typedef struct _MuMsg MuMsg;
MU_MSG_PRIORITY_LOW = 1,
MU_MSG_PRIORITY_NORMAL = 2,
MU_MSG_PRIORITY_HIGH = 3
};
typedef enum _MuMsgPriority MuMsgPriority;
/**
* initialize the message parsing system; this function must be called
* before doing any message parsing (ie., any of the other
* mu_msg functions). when done with the message parsing system,
* call mu_msg_uninit. Note: calling this function on an already
* initialized system has no effect
*/
void mu_msg_init (void);
/**
* uninitialize the messge parsing system that has previously been
* initialized with mu_msg_init. not calling mu_msg_uninit after
* mu_msg_init has been called will lead to memory leakage. Note:
* calling mu_msg_uninit on an uninitialized system has no
* effect
*/
void mu_msg_uninit (void);
/**
* create a new MuMsg* instance which parses a message and provides
* read access to its properties; call mu_msg_destroy when done with it.
*
* @param path full path to an email message file
*
* @param mdir the maildir for this message; ie, if the path is
* ~/Maildir/foo/bar/cur/msg, the maildir would be foo/bar; you can
* pass NULL for this parameter, in which case some maildir-specific
* information is not available.
*
* @return a new MuMsg instance or NULL in case of error
*/
MuMsg* mu_msg_new (const char* filepath,
const char *maildir);
/**
* destroy a MuMsg* instance; call this function when done with
* a MuMsg
*
* @param msg a MuMsg* instance or NULL
*/
void mu_msg_destroy (MuMsg *msg);
/**
* get the plain text body of this message
*
* @param msg a valid MuMsg* instance
*
* @return the plain text body or NULL in case of error or if there is no
* such body. the returned string should *not* be modified or freed.
* The returned data is in UTF8 or NULL.
*/
const char* mu_msg_get_body_text (MuMsg *msg);
/**
* get the html body of this message
*
* @param msg a valid MuMsg* instance
*
* @return the html body or NULL in case of error or if there is no
* such body. the returned string should *not* be modified or freed.
*/
const char* mu_msg_get_body_html (MuMsg *msg);
/**
* get a summary of the body of this message; a summary takes up to
* the first @max_lines from the message, and replaces newlines
* etc. with single whitespace characters. This only works if there's
* a text-body for the message
*
* @param msg a valid MuMsg* instance
* @param max_lines the max number of lines to summarize
*
* @return the summary of the message or NULL in case of error or if
* there is no such body. the returned string should *not* be modified
* or freed. When called multiple times, the function will always
* return the same summary, regardless of a different max_lines value.
*/
const char* mu_msg_get_summary (MuMsg *msg, size_t max_lines);
/**
* save a specific attachment to some targetdir
*
* @param msg a valid MuMsg instance
* @param wanted_idx index of the attachment you want to save
* @param targetdir filesystem directory to save the attachment
* @param overwrite existing files?
*
* @return TRUE if saving succeeded, FALSE otherwise
*/
gboolean
mu_msg_mime_part_save (MuMsg *msg, int wanted_idx,
const char *targetdir, gboolean overwrite);
/**
* get the sender (From:) of this message
*
* @param msg a valid MuMsg* instance
*
* @return the sender of this Message or NULL in case of error or if there
* is no sender. the returned string should *not* be modified or freed.
*/
const char* mu_msg_get_from (MuMsg *msg);
/**
* get the recipients (To:) of this message
*
* @param msg a valid MuMsg* instance
*
* @return the sender of this Message or NULL in case of error or if there
* are no recipients. the returned string should *not* be modified or freed.
*/
const char* mu_msg_get_to (MuMsg *msg);
/**
* get the carbon-copy recipients (Cc:) of this message
*
* @param msg a valid MuMsg* instance
*
* @return the Cc: recipients of this Message or NULL in case of error or if
* there are no such recipients. the returned string should *not* be modified
* or freed.
*/
const char* mu_msg_get_cc (MuMsg *msg);
/**
* get the file system path of this message
*
* @param msg a valid MuMsg* instance
*
* @return the path of this Message or NULL in case of error.
* the returned string should *not* be modified or freed.
*/
const char* mu_msg_get_path (MuMsg *msg);
/**
* get the maildir this message lives in; ie, if the path is
* ~/Maildir/foo/bar/cur/msg, the maildir would be foo/bar
*
* @param msg a valid MuMsg* instance
*
* @return the maildir requested or NULL in case of error. The returned
* string should *not* be modified or freed.
*/
const char* mu_msg_get_maildir (MuMsg *msg);
/**
* get the subject of this message
*
* @param msg a valid MuMsg* instance
*
* @return the subject of this Message or NULL in case of error or if there
* is no subject. the returned string should *not* be modified or freed.
*/
const char* mu_msg_get_subject (MuMsg *msg);
/**
* get the Message-Id of this message
*
* @param msg a valid MuMsg* instance
*
* @return the Message-Id of this Message (without the enclosing <>)
* or NULL in case of error or if there is none. the returned string
* should *not* be modified or freed.
*/
const char* mu_msg_get_msgid (MuMsg *msg);
/**
* get any arbitrary header from this message
*
* @param msg a valid MuMsg* instance
* @header the header requested
*
* @return the header requested or NULL in case of error or if there
* is no such header. the returned string should *not* be modified or freed.
*/
const char* mu_msg_get_header (MuMsg *msg,
const char* header);
/**
* get the message date/time (the Date: field) as time_t, using UTC
*
* @param msg a valid MuMsg* instance
*
* @return message date/time or 0 in case of error or if there
* is no such header.
*/
time_t mu_msg_get_date (MuMsg *msg);
/**
* get the flags for this message
*
* @param msg valid MuMsg* instance
*
* @return the fileflags as logically OR'd #Mu MsgFlags or 0 if
* there are none.
*/
MuMsgFlags mu_msg_get_flags (MuMsg *msg);
/**
* get the file size in bytes of this message
*
* @param msg a valid MuMsg* instance
*
* @return the filesize
*/
size_t mu_msg_get_size (MuMsg *msg);
/**
* get some field value as string
*
* @param msg a valid MuMsg instance
* @param field the field to retrieve; it must be a string-typed field
*
* @return a string that should not be freed
*/
const char* mu_msg_get_field_string (MuMsg *msg,
const MuMsgField* field);
/**
* get some field value as string
*
* @param msg a valid MuMsg instance
* @param field the field to retrieve; it must be a numeric field
*
* @return a string that should not be freed
*/
gint64 mu_msg_get_field_numeric (MuMsg *msg,
const MuMsgField* field);
/**
* get the message priority for this message (MU_MSG_PRIO_LOW,
* MU_MSG_PRIO_NORMAL or MU_MSG_PRIO_HIGH) the X-Priority,
* X-MSMailPriority, Importance and Precedence header are checked, in
* that order. if no known or explicit priority is set,
* MU_MSG_PRIO_NORMAL is assumed
*
* @param msg a valid MuMsg* instance
*
* @return the message priority (!= 0) or 0 in case of error
*/
MuMsgPrio mu_msg_get_prio (MuMsg *msg);
/**
* get the timestamp (mtime) for the file containing this message
*
* @param msg a valid MuMsg* instance
*
* @return the timestamp or 0 in case of error
*/
time_t mu_msg_get_timestamp (MuMsg *msg);
G_END_DECLS
#endif /*__MU_MSG_H__*/

View File

@ -25,7 +25,6 @@
#include <xapian.h>
#include "mu-msg.h"
#include "mu-msg-gmime.h"
#include "mu-store-xapian.h"
#include "mu-util.h"
@ -170,11 +169,11 @@ mu_store_xapian_flush (MuStoreXapian *store)
static void
add_terms_values_number (Xapian::Document& doc, MuMsgGMime *msg,
add_terms_values_number (Xapian::Document& doc, MuMsg *msg,
const MuMsgField* field)
{
const std::string pfx (mu_msg_field_xapian_prefix(field), 1);
gint64 num = mu_msg_gmime_get_field_numeric (msg, field);
gint64 num = mu_msg_get_field_numeric (msg, field);
const std::string numstr (Xapian::sortable_serialise((double)num));
doc.add_value ((Xapian::valueno)mu_msg_field_id(field), numstr);
@ -182,12 +181,12 @@ add_terms_values_number (Xapian::Document& doc, MuMsgGMime *msg,
}
static void
add_terms_values_string (Xapian::Document& doc, MuMsgGMime *msg,
add_terms_values_string (Xapian::Document& doc, MuMsg *msg,
const MuMsgField* field)
{
const char* str;
str = mu_msg_gmime_get_field_string (msg, field);
str = mu_msg_get_field_string (msg, field);
if (!str)
return;
@ -213,17 +212,17 @@ add_terms_values_string (Xapian::Document& doc, MuMsgGMime *msg,
}
static void
add_terms_values_body (Xapian::Document& doc, MuMsgGMime *msg,
add_terms_values_body (Xapian::Document& doc, MuMsg *msg,
const MuMsgField* field)
{
const char *str;
if (mu_msg_gmime_get_flags(msg) & MU_MSG_FLAG_ENCRYPTED)
if (mu_msg_get_flags(msg) & MU_MSG_FLAG_ENCRYPTED)
return; /* don't store encrypted bodies */
str = mu_msg_gmime_get_body_text (msg);
str = mu_msg_get_body_text (msg);
if (!str) /* FIXME: html->txt fallback needed */
str = mu_msg_gmime_get_body_html (msg);
str = mu_msg_get_body_html (msg);
if (!str)
return; /* no body... */
@ -235,7 +234,7 @@ add_terms_values_body (Xapian::Document& doc, MuMsgGMime *msg,
struct _MsgDoc {
Xapian::Document *_doc;
MuMsgGMime *_msg;
MuMsg *_msg;
};
typedef struct _MsgDoc MsgDoc;
@ -284,15 +283,15 @@ get_message_uid (const char* path)
}
static std::string
get_message_uid (MuMsgGMime *msg)
get_message_uid (MuMsg *msg)
{
return get_message_uid (mu_msg_gmime_get_path(msg));
return get_message_uid (mu_msg_get_path(msg));
}
MuResult
mu_store_xapian_store (MuStoreXapian *store, MuMsgGMime *msg)
mu_store_xapian_store (MuStoreXapian *store, MuMsg *msg)
{
g_return_val_if_fail (store, MU_ERROR);
g_return_val_if_fail (msg, MU_ERROR);

View File

@ -1,5 +1,5 @@
/*
** Copyright (C) 2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify it
** under the terms of the GNU General Public License as published by the
@ -24,7 +24,7 @@
#include <inttypes.h>
#include "mu-result.h"
#include "mu-msg-gmime.h"
#include "mu-msg.h"
G_BEGIN_DECLS
@ -85,8 +85,7 @@ void mu_store_xapian_flush (MuStoreXapian *store);
*
* @return TRUE if it succeeded, FALSE otherwise
*/
MuResult mu_store_xapian_store (MuStoreXapian *store,
MuMsgGMime *msg);
MuResult mu_store_xapian_store (MuStoreXapian *store, MuMsg *msg);
/**

View File

@ -44,9 +44,9 @@ TEST_PROGS += test-mu-query
test_mu_query_SOURCES= test-mu-query.c dummy.cc
test_mu_query_LDADD= libtestmucommon.la
TEST_PROGS += test-mu-msg-gmime
test_mu_msg_gmime_SOURCES= test-mu-msg-gmime.c
test_mu_msg_gmime_LDADD= libtestmucommon.la
TEST_PROGS += test-mu-msg
test_mu_msg_SOURCES= test-mu-msg.c
test_mu_msg_LDADD= libtestmucommon.la
libtestmucommon_la_SOURCES= \

View File

@ -1,209 +0,0 @@
/*
** Copyright (C) 2008-2010 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** This program is free software; you can redistribute it and/or modify it
** under the terms of the GNU General Public License as published by the
** Free Software Foundation; either version 3, or (at your option) any
** later version.
**
** This program 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
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software Foundation,
** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /*HAVE_CONFIG_H*/
#include <glib.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <locale.h>
#include "test-mu-common.h"
#include "src/mu-msg-gmime.h"
static gchar*
get_mailpath (unsigned idx)
{
const char* mailfile;
switch (idx) {
case 1: mailfile = "cur/1220863042.12663_1.mindcrime!2,S"; break;
case 2: mailfile = "cur/1220863087.12663_19.mindcrime!2,S"; break;
default: mailfile = NULL;
}
if (mailfile)
return g_strdup_printf ("%s/%s", MU_TESTMAILDIR, mailfile);
else
return NULL;
}
static gboolean
each_contact (MuMsgContact *contact, GSList **lst)
{
char *addr;
addr = g_strdup_printf ("%s <%s>",
contact->name ? contact->name : "<none>",
contact->address ? contact->address : "<none>");
*lst = g_slist_append (*lst, addr);
return TRUE;
}
static void
test_mu_msg_gmime_01 (void)
{
char *mfile;
MuMsgGMime *msg;
GSList *lst;
mu_msg_gmime_init ();
mfile = get_mailpath (1);
msg = mu_msg_gmime_new (mfile, NULL);
g_assert_cmpstr (mu_msg_gmime_get_to(msg),
==, "Donald Duck <gcc-help@gcc.gnu.org>");
g_assert_cmpstr (mu_msg_gmime_get_subject(msg),
==, "gcc include search order");
g_assert_cmpstr (mu_msg_gmime_get_from(msg),
==, "Mickey Mouse <anon@example.com>");
g_assert_cmpstr (mu_msg_gmime_get_msgid(msg),
==, "3BE9E6535E3029448670913581E7A1A20D852173@"
"emss35m06.us.lmco.com");
g_assert_cmpstr (mu_msg_gmime_get_header(msg, "Mailing-List"),
==, "contact gcc-help-help@gcc.gnu.org; run by ezmlm");
g_assert_cmpuint (mu_msg_gmime_get_priority(msg), /* 'klub' */
==, MU_MSG_PRIORITY_NORMAL);
g_assert_cmpuint (mu_msg_gmime_get_date(msg),
==, 1217530645);
{
GSList *lst, *cur;
lst = mu_msg_gmime_get_contacts (msg);
g_assert_cmpuint (g_slist_length(lst),==, 2);
cur = lst;
g_assert_cmpstr (mu_msg_contact_name ((MuMsgContact*)cur->data),
==, "Mickey Mouse");
g_assert_cmpstr (mu_msg_contact_address ((MuMsgContact*)cur->data),
==, "anon@example.com");
cur = g_slist_next (cur);
g_assert_cmpstr (mu_msg_contact_name ((MuMsgContact*)cur->data),
==, "Donald Duck");
g_assert_cmpstr (mu_msg_contact_address ((MuMsgContact*)cur->data),
==, "gcc-help@gcc.gnu.org");
mu_msg_contacts_free (lst);
}
mu_msg_gmime_destroy (msg);
g_free (mfile);
mu_msg_gmime_uninit ();
}
static void
test_mu_msg_gmime_02 (void)
{
char *mfile;
MuMsgGMime *msg;
GSList *lst;
mu_msg_gmime_init ();
mfile = get_mailpath (2);
msg = mu_msg_gmime_new (mfile, NULL);
g_assert_cmpstr (mu_msg_gmime_get_to(msg),
==, "help-gnu-emacs@gnu.org");
g_assert_cmpstr (mu_msg_gmime_get_subject(msg),
==, "Re: Learning LISP; Scheme vs elisp.");
g_assert_cmpstr (mu_msg_gmime_get_from(msg),
==, "anon@example.com");
g_assert_cmpstr (mu_msg_gmime_get_msgid(msg),
==, "r6bpm5-6n6.ln1@news.ducksburg.com");
g_assert_cmpstr (mu_msg_gmime_get_header(msg, "Errors-To"),
==, "help-gnu-emacs-bounces+xxxx.klub=gmail.com@gnu.org");
g_assert_cmpuint (mu_msg_gmime_get_priority(msg), /* 'low' */
==, MU_MSG_PRIORITY_LOW);
g_assert_cmpuint (mu_msg_gmime_get_date(msg),
==, 1218051515);
{
GSList *lst, *cur;
lst = mu_msg_gmime_get_contacts (msg);
g_assert_cmpuint (g_slist_length(lst),==, 2);
cur = lst;
g_assert_cmpstr (mu_msg_contact_name ((MuMsgContact*)cur->data),
==, NULL);
g_assert_cmpstr (mu_msg_contact_address ((MuMsgContact*)cur->data),
==, "anon@example.com");
cur = g_slist_next (cur);
g_assert_cmpstr (mu_msg_contact_name ((MuMsgContact*)cur->data),
==, NULL);
g_assert_cmpstr (mu_msg_contact_address ((MuMsgContact*)cur->data),
==, "help-gnu-emacs@gnu.org");
mu_msg_contacts_free (lst);
}
mu_msg_gmime_destroy (msg);
g_free (mfile);
mu_msg_gmime_uninit ();
}
static gboolean
ignore_error (const char* log_domain, GLogLevelFlags log_level, const gchar* msg,
gpointer user_data)
{
return FALSE; /* don't abort */
}
static void
shutup (void) {}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
/* mu_msg_str_date */
g_test_add_func ("/mu-msg-gmime/mu-msg-gmime-01",
test_mu_msg_gmime_01);
g_test_add_func ("/mu-msg-gmime/mu-msg-gmime-02",
test_mu_msg_gmime_02);
g_log_set_handler (NULL,
G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION,
(GLogFunc)shutup, NULL);
return g_test_run ();
}

View File

@ -102,9 +102,9 @@ test_mu_msg_str_size_02 (void)
static void
test_mu_msg_str_prio_01 (void)
{
g_assert_cmpstr (mu_msg_str_prio(MU_MSG_PRIORITY_LOW), ==, "low");
g_assert_cmpstr (mu_msg_str_prio(MU_MSG_PRIORITY_NORMAL), ==, "normal");
g_assert_cmpstr (mu_msg_str_prio(MU_MSG_PRIORITY_HIGH), ==, "high");
g_assert_cmpstr (mu_msg_str_prio(MU_MSG_PRIO_LOW), ==, "low");
g_assert_cmpstr (mu_msg_str_prio(MU_MSG_PRIO_NORMAL), ==, "normal");
g_assert_cmpstr (mu_msg_str_prio(MU_MSG_PRIO_HIGH), ==, "high");
}