mail-notification

Fork of Jean-Yves Lefort's mail-notification, a tray icon to notify of new mail
git clone https://code.djc.id.au/git/mail-notification/

src/mn-mh-mailbox-backend.gob (6940B) - raw

      1 /*
      2  * Mail Notification
      3  * Copyright (C) 2003-2008 Jean-Yves Lefort <jylefort@brutele.be>
      4  *
      5  * This program is free software; you can redistribute it and/or modify
      6  * it under the terms of the GNU General Public License as published by
      7  * the Free Software Foundation; either version 3 of the License, or
      8  * (at your option) any later version.
      9  *
     10  * This program is distributed in the hope that it will be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13  * GNU General Public License for more details.
     14  *
     15  * You should have received a copy of the GNU General Public License along
     16  * with this program; if not, write to the Free Software Foundation, Inc.,
     17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     18  */
     19 
     20 %headertop{
     21 #include "mn-vfs-mailbox-backend.h"
     22 %}
     23 
     24 %{
     25 #include <glib/gi18n.h>
     26 #include "mn-mailbox-private.h"
     27 #include "mn-reentrant-mailbox-private.h"
     28 #include "mn-vfs-mailbox-backend-private.h"
     29 #include "mn-vfs.h"
     30 #include "mn-util.h"
     31 #include "mn-message-mime.h"
     32 
     33 #define SEQUENCES_FILE			".mh_sequences"
     34 #define XMH_CACHE_FILE			".xmhcache"
     35 %}
     36 
     37 class MN:MH:Mailbox:Backend from MN:VFS:Mailbox:Backend
     38 {
     39   class_init (class)
     40   {
     41     MN_VFS_MAILBOX_BACKEND_CLASS(class)->format = "MH";
     42   }
     43 
     44   constructor (self)
     45   {
     46     MNVFSMailboxBackend *backend = MN_VFS_MAILBOX_BACKEND(self);
     47 
     48     /*
     49      * There is no standard way of locking a MH mailbox, so avoid race
     50      * conditions by setting a check latency of 3 seconds.
     51      */
     52 
     53     backend->check_latency = 3000;
     54   }
     55 
     56   override (MN:VFS:Mailbox:Backend) void
     57     monitor_cb (MNVFSMailboxBackend *backend,
     58 		const char *info_uri,
     59 		GnomeVFSMonitorEventType event_type)
     60   {
     61     if (event_type == GNOME_VFS_MONITOR_EVENT_CHANGED
     62 	|| event_type == GNOME_VFS_MONITOR_EVENT_DELETED
     63 	|| event_type == GNOME_VFS_MONITOR_EVENT_CREATED)
     64       {
     65 	char *filename;
     66 
     67 	filename = mn_vfs_uri_extract_short_name(info_uri);
     68 	if (filename)
     69 	  {
     70 	    if (! strcmp(filename, SEQUENCES_FILE) || mn_str_isnumeric(filename))
     71 	      mn_vfs_mailbox_backend_queue_check(backend);
     72 
     73 	    g_free(filename);
     74 	  }
     75       }
     76   }
     77 
     78   override (MN:VFS:Mailbox:Backend) gboolean
     79     is (MNVFSMailboxBackend *dummy,
     80 	MNVFSMailboxBackendClass *class,
     81 	MNVFSMailbox *mailbox)
     82   {
     83     GnomeVFSURI *sequences_uri;
     84     gboolean is;
     85 
     86     sequences_uri = gnome_vfs_uri_append_file_name(mailbox->vfs_uri, SEQUENCES_FILE);
     87     is = mn_vfs_test(sequences_uri, G_FILE_TEST_IS_REGULAR);
     88     gnome_vfs_uri_unref(sequences_uri);
     89 
     90     if (! is)
     91       {
     92 	GnomeVFSURI *cache_uri;
     93 
     94 	cache_uri = gnome_vfs_uri_append_file_name(mailbox->vfs_uri, XMH_CACHE_FILE);
     95 	is = mn_vfs_test(cache_uri, G_FILE_TEST_IS_REGULAR);
     96 	gnome_vfs_uri_unref(cache_uri);
     97       }
     98 
     99     return is;
    100   }
    101 
    102   override (MN:VFS:Mailbox:Backend) void
    103     check (MNVFSMailboxBackend *backend, int check_id)
    104   {
    105     GnomeVFSURI *sequences_uri;
    106     GnomeVFSResult result;
    107     GnomeVFSHandle *handle;
    108 
    109     mn_vfs_mailbox_backend_monitor(backend, check_id, backend->mailbox->uri, GNOME_VFS_MONITOR_DIRECTORY);
    110 
    111     sequences_uri = gnome_vfs_uri_append_file_name(backend->mailbox->vfs_uri, SEQUENCES_FILE);
    112     result = gnome_vfs_open_uri(&handle, sequences_uri, GNOME_VFS_OPEN_READ);
    113     gnome_vfs_uri_unref(sequences_uri);
    114 
    115     if (result == GNOME_VFS_OK)
    116       {
    117 	MNVFSReadLineContext *context = NULL;
    118 	const char *line;
    119 	GSList *messages = NULL;
    120 	int num_errors = 0;
    121 	GnomeVFSResult close_result;
    122 
    123 	while ((result = mn_vfs_read_line(&context, handle, &line)) == GNOME_VFS_OK)
    124 	  if (g_str_has_prefix(line, "unseen: "))
    125 	    {
    126 	      int first;
    127 	      char **elements;
    128 	      int i;
    129 
    130 	      elements = g_strsplit(line + 8, " ", 0);
    131 	      for (i = 0; elements[i]; i++)
    132 		{
    133 		  int last;
    134 		  int n;
    135 
    136 		  n = sscanf(elements[i], "%d-%d", &first, &last);
    137 		  if (n >= 1)
    138 		    {
    139 		      int j;
    140 
    141 		      if (n == 1)
    142 			last = first;
    143 
    144 		      for (j = first; j <= last; j++)
    145 			{
    146 			  char *filename;
    147 			  GnomeVFSURI *message_uri;
    148 			  MNMessage *message;
    149 			  GError *err = NULL;
    150 
    151 			  if (mn_reentrant_mailbox_check_aborted(MN_REENTRANT_MAILBOX(backend->mailbox), check_id))
    152 			    {
    153 			      g_strfreev(elements);
    154 			      goto loop_end;
    155 			    }
    156 
    157 			  filename = g_strdup_printf("%i", j);
    158 			  message_uri = gnome_vfs_uri_append_file_name(backend->mailbox->vfs_uri, filename);
    159 			  g_free(filename);
    160 
    161 			  /*
    162 			   * We set handle_status to FALSE, since
    163 			   * messages in the unseen sequence are by
    164 			   * definition unseen (that is, new).
    165 			   */
    166 
    167 			  message = mn_message_new_from_uri(MN_MAILBOX(backend->mailbox),
    168 							    message_uri,
    169 							    MN_MESSAGE_NEW,
    170 							    FALSE,
    171 							    &err);
    172 			  if (message)
    173 			    messages = g_slist_prepend(messages, message);
    174 			  else if (err)
    175 			    {
    176 			      char *message_text_uri;
    177 
    178 			      message_text_uri = gnome_vfs_uri_to_string(message_uri, GNOME_VFS_URI_HIDE_PASSWORD);
    179 			      mn_mailbox_warning(MN_MAILBOX(backend->mailbox), "cannot read message \"%s\": %s",
    180 						 message_text_uri, err->message);
    181 			      g_free(message_text_uri);
    182 			      g_error_free(err);
    183 
    184 			      num_errors++;
    185 			    }
    186 
    187 			  gnome_vfs_uri_unref(message_uri);
    188 			}
    189 		    }
    190 		}
    191 	      g_strfreev(elements);
    192 	    }
    193 
    194       loop_end:
    195 	mn_vfs_read_line_context_free(context);
    196 	close_result = gnome_vfs_close(handle);
    197 
    198 	GDK_THREADS_ENTER();
    199 
    200 	if (! mn_reentrant_mailbox_check_aborted(MN_REENTRANT_MAILBOX(backend->mailbox), check_id))
    201 	  {
    202 	    if (result == GNOME_VFS_ERROR_EOF || result == GNOME_VFS_OK)
    203 	      {
    204 		if (close_result == GNOME_VFS_OK)
    205 		  {
    206 		    mn_mailbox_set_messages(MN_MAILBOX(backend->mailbox), messages);
    207 
    208 		    if (num_errors != 0)
    209 		      mn_mailbox_set_error(MN_MAILBOX(backend->mailbox),
    210 					   ngettext("cannot read %i message",
    211 						    "cannot read %i messages",
    212 						    num_errors),
    213 					   num_errors);
    214 		  }
    215 		else
    216 		  mn_mailbox_set_error(MN_MAILBOX(backend->mailbox), _("unable to close %s: %s"), SEQUENCES_FILE, gnome_vfs_result_to_string(close_result));
    217 	      }
    218 	    else
    219 	      mn_mailbox_set_error(MN_MAILBOX(backend->mailbox), _("error while reading %s: %s"), SEQUENCES_FILE, gnome_vfs_result_to_string(result));
    220 	  }
    221 
    222 	mn_g_object_slist_free(messages);
    223 
    224 	gdk_flush();
    225 	GDK_THREADS_LEAVE();
    226       }
    227     else
    228       {
    229 	GnomeVFSURI *cache_uri;
    230 	gboolean cache_exists;
    231 
    232 	cache_uri = gnome_vfs_uri_append_file_name(backend->mailbox->vfs_uri, XMH_CACHE_FILE);
    233 	cache_exists = mn_vfs_test(cache_uri, G_FILE_TEST_IS_REGULAR);
    234 	gnome_vfs_uri_unref(cache_uri);
    235 
    236 	if (! mn_reentrant_mailbox_check_aborted(MN_REENTRANT_MAILBOX(backend->mailbox), check_id))
    237 	  {
    238 	    GDK_THREADS_ENTER();
    239 
    240 	    if (cache_exists)
    241 	      mn_mailbox_set_messages(MN_MAILBOX(backend->mailbox), NULL);
    242 	    else
    243 	      mn_mailbox_set_error(MN_MAILBOX(backend->mailbox), _("unable to open %s: %s"), SEQUENCES_FILE, gnome_vfs_result_to_string(result));
    244 
    245 	    gdk_flush();
    246 	    GDK_THREADS_LEAVE();
    247 	  }
    248       }
    249   }
    250 }