Changeset 2267

Show
Ignore:
Timestamp:
06/25/07 18:22:32
Author:
pvanhoof
Message:

Deleting attachments from message cache

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ChangeLog

    r2262 r2267  
    22         
    33        * Deleting messages from local folders (bugfix about ghost rows) 
     4        * Deleting attachments from message cache 
     5 
     6        * This was a major API change 
    47 
    582007-06-24  Philip Van Hoof  <pvanhoof@gnome.org> 
  • trunk/libtinymail-camel/camel-lite/camel/camel-data-cache.c

    r1944 r2267  
    4444#include "camel-stream-mem.h" 
    4545#include "camel-file-utils.h" 
     46 
     47#include "camel-stream-buffer.h" 
     48 
    4649 
    4750extern int camel_verbose_debug; 
     
    432435} 
    433436 
     437#ifndef _GNU_SOURCE 
     438#define _GNU_SOURCE 
     439#endif 
     440 
     441void 
     442camel_data_cache_delete_attachments (CamelDataCache *cdc, const char *path, const char *key) 
     443{ 
     444  CamelStream *in = camel_data_cache_get (cdc, path, key, NULL); 
     445  gchar *real1 = data_cache_path(cdc, FALSE, path, key); 
     446  gchar *real = g_strdup_printf ("%s.tmp", real1); 
     447  CamelStream *to = camel_stream_fs_new_with_name (real, O_RDWR|O_CREAT|O_TRUNC, 0600); 
     448 
     449  if (in && to) 
     450  { 
     451        CamelStreamBuffer *stream = (CamelStreamBuffer *) camel_stream_buffer_new (in, CAMEL_STREAM_BUFFER_READ); 
     452        char *buffer; 
     453        int w = 0, n; 
     454        gchar *boundary = NULL; 
     455        gboolean occurred = FALSE, theend = FALSE; 
     456        unsigned int len; 
     457 
     458        /* We write an '*' to the start of the stream to say its not complete yet */ 
     459        if ((n = camel_stream_write(to, "*", 1)) == -1) 
     460                theend = TRUE; 
     461 
     462        while (!theend) 
     463        { 
     464                buffer = camel_stream_buffer_read_line (stream); 
     465 
     466                if (!buffer) { 
     467                        theend = TRUE; 
     468                        continue; 
     469                } 
     470 
     471                len = strlen (buffer); 
     472 
     473                if (boundary == NULL) 
     474                { 
     475                           CamelContentType *ct = NULL; 
     476                           const char *bound=NULL; 
     477                           char *pstr = (char*)strcasestr ((const char *) buffer, "boundary"); 
     478 
     479                           if (pstr)  
     480                           { 
     481                                char *end; 
     482                                pstr = strchr (pstr, '"');  
     483                                if (pstr) {  
     484                                        pstr++; 
     485                                        end = strchr (pstr, '"'); 
     486                                        if (end) { 
     487                                                *end='\0'; 
     488                                                boundary = g_strdup (pstr); 
     489                                        } 
     490                                } 
     491                           } 
     492 
     493                           if (ct)  
     494                           {  
     495                                bound = camel_content_type_param(ct, "boundary"); 
     496                                if (bound && strlen (bound) > 0)  
     497                                        boundary = g_strdup (bound); 
     498                           } 
     499                } else if (strstr ((const char*) buffer, (const char*) boundary)) 
     500                { 
     501                        if (occurred) 
     502                                theend = TRUE; 
     503                        occurred = TRUE; 
     504                } 
     505 
     506                if (!theend) 
     507                { 
     508                    n = camel_stream_write(to, (const char*) buffer, len); 
     509                    if (n == -1 || camel_stream_write(to, "\n", 1) == -1) 
     510                        break; 
     511                    w += n+1; 
     512                } else if (boundary != NULL) 
     513                { 
     514                    gchar *nb = g_strdup_printf ("\n--%s\n", boundary); 
     515                    n = camel_stream_write(to, nb, strlen (nb)); 
     516                    g_free (nb); 
     517                } 
     518        } 
     519 
     520        /* it all worked, output a '#' to say we're a-ok */ 
     521        if (n != -1 || theend) { 
     522                camel_stream_reset(to); 
     523                n = camel_stream_write(to, "#", 1); 
     524                if (theend) 
     525                        camel_data_cache_set_partial (cdc, path, key, TRUE); 
     526                else 
     527                        camel_data_cache_set_partial (cdc, path, key, FALSE); 
     528        } 
     529 
     530        camel_object_unref (stream); 
     531        camel_object_unref (in); 
     532        if (boundary) 
     533                g_free (boundary); 
     534        camel_object_unref (to); 
     535 
     536        camel_data_cache_remove (cdc, path, key, NULL); 
     537        rename (real, real1); 
     538  } 
     539 
     540  g_free (real); 
     541  g_free (real1); 
     542 
     543} 
     544 
    434545/** 
    435546 * camel_data_cache_remove: 
  • trunk/libtinymail-camel/camel-lite/camel/camel-data-cache.h

    r1943 r2267  
    9393void         camel_data_cache_set_partial (CamelDataCache *cache, const char *path, 
    9494                                              const char *uid, gboolean partial); 
     95void         camel_data_cache_delete_attachments (CamelDataCache *cdc, const char *path,  
     96                                              const char *key); 
    9597 
    9698void camel_data_cache_set_flags (CamelDataCache *cdc, const char *path, CamelMessageInfoBase *mi); 
  • trunk/libtinymail-camel/camel-lite/camel/camel-folder.c

    r2238 r2267  
    8686                            CamelException *ex); 
    8787 
    88  
    8988static GPtrArray        *get_uids            (CamelFolder *folder); 
    9089static void              free_uids           (CamelFolder *folder, 
     
    118117 
    119118static int get_local_size (CamelFolder *folder); 
     119 
     120static void  
     121delete_attachments (CamelFolder *folder, const char *uid) 
     122{ 
     123} 
    120124 
    121125static void  
     
    173177        camel_folder_class->thaw = thaw; 
    174178        camel_folder_class->is_frozen = is_frozen; 
     179        camel_folder_class->delete_attachments = delete_attachments; 
    175180 
    176181        /* virtual method overload */ 
     
    319324 
    320325        CF_CLASS (folder)->refresh_info (folder, ex); 
     326} 
     327 
     328void  
     329camel_folder_delete_attachments (CamelFolder *folder, const char *uid) 
     330{ 
     331        g_return_if_fail (CAMEL_IS_FOLDER (folder)); 
     332 
     333        return CF_CLASS (folder)->delete_attachments (folder, uid); 
    321334} 
    322335 
  • trunk/libtinymail-camel/camel-lite/camel/camel-folder.h

    r2238 r2267  
    205205        void (*set_push_email) (CamelFolder *folder, gboolean setting); 
    206206 
     207        void (*delete_attachments) (CamelFolder *folder, const char *uid); 
     208 
    207209} CamelFolderClass; 
    208210 
     
    361363int camel_folder_get_local_size   (CamelFolder *folder); 
    362364 
     365void camel_folder_delete_attachments (CamelFolder *folder, const char *uid); 
     366 
    363367G_END_DECLS 
    364368 
  • trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-folder.c

    r2238 r2267  
    162162GPtrArray* _camel_imap_store_get_recent_messages (CamelImapStore *imap_store, const char *folder_name, int *messages, int *unseen, gboolean withthem); 
    163163 
     164static void imap_delete_attachments (CamelFolder *folder, const char *uid); 
     165 
     166 
    164167#ifdef G_OS_WIN32 
    165168/* The strtok() in Microsoft's C library is MT-safe (but still uses 
     
    191194        camel_folder_class->search_free = imap_search_free; 
    192195        camel_folder_class->thaw = imap_thaw; 
     196        camel_folder_class->delete_attachments = imap_delete_attachments; 
    193197 
    194198        camel_disco_folder_class->refresh_info_online = imap_refresh_info; 
     
    333337 
    334338        return folder; 
     339} 
     340 
     341static void 
     342imap_delete_attachments (CamelFolder *folder, const char *uid) 
     343{ 
     344        CamelImapMessageCache *cache = CAMEL_IMAP_FOLDER (folder)->cache; 
     345        camel_imap_message_cache_delete_attachments (cache, uid); 
     346        return; 
    335347} 
    336348 
  • trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-message-cache.c

    r1943 r2267  
    3838 
    3939#include "camel-imap-message-cache.h" 
     40#include "camel-stream-buffer.h" 
    4041 
    4142#ifndef O_BINARY 
     
    505506         
    506507        return stream; 
     508} 
     509 
     510 
     511 
     512void 
     513camel_imap_message_cache_delete_attachments (CamelImapMessageCache *cache, const char *uid) 
     514{ 
     515  CamelStream *in = camel_imap_message_cache_get (cache, uid, "", NULL); 
     516  gchar *real1 = g_strdup_printf ("%s/%s.", cache->path, uid); 
     517  gchar *real = g_strdup_printf ("%s.tmp", real1); 
     518  CamelStream *to = camel_stream_fs_new_with_name (real, O_RDWR|O_CREAT|O_TRUNC, 0600); 
     519 
     520  if (in && to) 
     521  { 
     522        CamelStreamBuffer *stream = (CamelStreamBuffer *) camel_stream_buffer_new (in, CAMEL_STREAM_BUFFER_READ); 
     523        char *buffer; 
     524        int w = 0, n; 
     525        gchar *boundary = NULL; 
     526        gboolean occurred = FALSE, theend = FALSE; 
     527        unsigned int len; 
     528 
     529        /* if ((n = camel_stream_write(to, "*", 1)) == -1) 
     530                theend = TRUE; */ 
     531 
     532        while (!theend) 
     533        { 
     534                buffer = camel_stream_buffer_read_line (stream); 
     535 
     536                if (!buffer) { 
     537                        theend = TRUE; 
     538                        continue; 
     539                } 
     540 
     541                len = strlen (buffer); 
     542 
     543                if (boundary == NULL) 
     544                { 
     545                           CamelContentType *ct = NULL; 
     546                           const char *bound=NULL; 
     547                           char *pstr = (char*)strcasestr ((const char *) buffer, "boundary"); 
     548 
     549                           if (pstr)  
     550                           { 
     551                                char *end; 
     552                                pstr = strchr (pstr, '"');  
     553                                if (pstr) {  
     554                                        pstr++; 
     555                                        end = strchr (pstr, '"'); 
     556                                        if (end) { 
     557                                                *end='\0'; 
     558                                                boundary = g_strdup (pstr); 
     559                                        } 
     560                                } 
     561                           } 
     562 
     563                           if (ct)  
     564                           {  
     565                                bound = camel_content_type_param(ct, "boundary"); 
     566                                if (bound && strlen (bound) > 0)  
     567                                        boundary = g_strdup (bound); 
     568                           } 
     569                } else if (strstr ((const char*) buffer, (const char*) boundary)) 
     570                { 
     571                        if (occurred) 
     572                                theend = TRUE; 
     573                        occurred = TRUE; 
     574                } 
     575 
     576                if (!theend) 
     577                { 
     578                    n = camel_stream_write(to, (const char*) buffer, len); 
     579                    if (n == -1 || camel_stream_write(to, "\n", 1) == -1) 
     580                        break; 
     581                    w += n+1; 
     582                } else if (boundary != NULL) 
     583                { 
     584                    gchar *nb = g_strdup_printf ("\n--%s\n", boundary); 
     585                    n = camel_stream_write(to, nb, strlen (nb)); 
     586                    g_free (nb); 
     587                } 
     588        } 
     589 
     590        /* it all worked, output a '#' to say we're a-ok */ 
     591        if (n != -1 || theend) { 
     592                camel_stream_reset(to); 
     593                /* n = camel_stream_write(to, "#", 1); */ 
     594                if (theend) 
     595                        camel_imap_message_cache_set_partial (cache, uid, TRUE); 
     596                else 
     597                        camel_imap_message_cache_set_partial (cache, uid, FALSE); 
     598        } 
     599 
     600        camel_object_unref (stream); 
     601        camel_object_unref (in); 
     602        if (boundary) 
     603                g_free (boundary); 
     604        camel_object_unref (to); 
     605 
     606        camel_imap_message_cache_remove (cache, uid); 
     607        rename (real, real1); 
     608  } 
     609 
     610  g_free (real); 
     611  g_free (real1); 
     612 
    507613} 
    508614 
  • trunk/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-message-cache.h

    r1943 r2267  
    106106void camel_imap_message_cache_set_flags (const gchar *folder_dir, CamelMessageInfoBase *mi); 
    107107 
     108void camel_imap_message_cache_delete_attachments (CamelImapMessageCache *cache, const char *uid); 
     109 
    108110 
    109111/* Standard Camel function */ 
  • trunk/libtinymail-camel/camel-lite/camel/providers/pop3/camel-pop3-folder.c

    r2243 r2267  
    6262#include "camel-disco-diary.h" 
    6363 
     64#include "camel-stream-buffer.h" 
     65 
    6466#define d(x)  
    6567 
     
    7779static CamelMimeMessage *pop3_get_top (CamelFolder *folder, const char *uid, CamelException *ex); 
    7880static int pop3_get_local_size (CamelFolder *folder); 
     81 
     82static void pop3_delete_attachments (CamelFolder *folder, const char *uid); 
    7983 
    8084 
     
    735739 
    736740 
     741static void 
     742pop3_delete_attachments (CamelFolder *folder, const char *uid) 
     743{ 
     744        CamelPOP3Store *pop3_store = CAMEL_POP3_STORE (folder->parent_store); 
     745        camel_data_cache_delete_attachments (pop3_store->cache, "cache", uid); 
     746        return; 
     747} 
     748 
    737749static CamelMimeMessage * 
    738750pop3_get_message (CamelFolder *folder, const char *uid, CamelFolderReceiveType type, gint param, CamelException *ex) 
     
    756768                if (camel_data_wrapper_construct_from_stream((CamelDataWrapper *)message, stream) == -1) { 
    757769                        if (errno == EINTR) 
    758                                 camel_exception_setv(ex, CAMEL_EXCEPTION_USER_CANCEL, _("User canceled")); 
     770                                camel_exception_setv(ex, CAMEL_EXCEPTION_USER_CANCEL, "User canceled"); 
    759771                        else 
    760772                                camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, 
    761                                                       _("Cannot get message %s: %s")
     773                                                      "Cannot get message %s: %s"
    762774                                                      uid, g_strerror (errno)); 
    763                         camel_object_unref((CamelObject *)message); 
     775                        if (message) 
     776                                camel_object_unref (message); 
    764777                        message = NULL; 
    765778                } 
     
    12551268        camel_folder_class->get_message = pop3_get_message; 
    12561269        camel_folder_class->set_message_flags = pop3_set_message_flags; 
     1270        camel_folder_class->delete_attachments = pop3_delete_attachments; 
    12571271 
    12581272        camel_disco_folder_class->refresh_info_online = pop3_refresh_info; 
  • trunk/libtinymail-camel/camel-lite/camel/providers/pop3/camel-pop3-stream.c

    r2257 r2267  
    106106                                is->mode = CAMEL_POP3_STREAM_EOD; 
    107107                                is->state = 0; 
    108                                 pop3_debug ("POP3_STREAM_READ(%d):\n%s\n", (int)(o-buffer), buffer); 
     108                                pop3_debug ("POP3_STREAM_READ %d bytes:\n", (int)(o-buffer)); 
    109109                                return o-buffer; 
    110110                        } 
     
    139139        is->state = state; 
    140140 
    141         pop3_debug ("POP3_STREAM_READ(%d):\n%.*s\n", (int)(o-buffer), (int)(o-buffer), buffer); 
     141        pop3_debug ("POP3_STREAM_READ %d bytes\n", (int)(o-buffer)); 
    142142 
    143143        return o-buffer; 
  • trunk/libtinymail-camel/tny-camel-folder-priv.h

    r2091 r2267  
    7373void _tny_camel_folder_reason (TnyCamelFolderPriv *priv); 
    7474 
     75void _tny_camel_folder_uncache_attachments (TnyCamelFolder *self, const gchar *uid); 
     76 
    7577void _tny_camel_folder_remove_folder_actual (TnyFolderStore *self, TnyFolder *folder, GError **err); 
    7678 
  • trunk/libtinymail-camel/tny-camel-folder.c

    r2256 r2267  
    140140} 
    141141 
    142  
    143142void  
    144143_tny_camel_folder_check_unread_count (TnyCamelFolder *self) 
     
    434433} 
    435434 
     435void  
     436_tny_camel_folder_uncache_attachments (TnyCamelFolder *self, const gchar *uid) 
     437{ 
     438        TnyCamelFolderPriv *priv = TNY_CAMEL_FOLDER_GET_PRIVATE (self); 
     439 
     440        g_static_rec_mutex_lock (priv->folder_lock); 
     441 
     442        if (!priv->folder || !priv->loaded || !CAMEL_IS_FOLDER (priv->folder)) 
     443                if (!load_folder_no_lock (priv)) 
     444                { 
     445                        g_static_rec_mutex_unlock (priv->folder_lock); 
     446                        return; 
     447                } 
     448 
     449        camel_folder_delete_attachments (priv->folder, uid); 
     450 
     451        g_static_rec_mutex_unlock (priv->folder_lock); 
     452} 
    436453 
    437454static void  
  • trunk/libtinymail-camel/tny-camel-msg.c

    r2194 r2267  
    224224 
    225225 
     226static void  
     227tny_camel_msg_uncache_attachments (TnyMsg *self) 
     228{ 
     229        TNY_CAMEL_MSG_GET_CLASS (self)->uncache_attachments_func (self); 
     230} 
     231 
     232static void  
     233tny_camel_msg_uncache_attachments_default (TnyMsg *self) 
     234{ 
     235        TnyCamelMsgPriv *priv = TNY_CAMEL_MSG_GET_PRIVATE (self); 
     236 
     237        if (priv->folder && priv->header) 
     238        { 
     239                _tny_camel_folder_uncache_attachments ( 
     240                        TNY_CAMEL_FOLDER (priv->folder), 
     241                        tny_header_get_uid (priv->header)); 
     242        } 
     243} 
     244 
    226245static void 
    227246tny_camel_msg_finalize (GObject *object) 
     
    302321        klass->get_folder_func = tny_camel_msg_get_folder; 
    303322        klass->get_url_string_func = tny_camel_msg_get_url_string; 
     323        klass->uncache_attachments_func = tny_camel_msg_uncache_attachments; 
    304324 
    305325        return; 
     
    317337        class->get_folder_func = tny_camel_msg_get_folder_default; 
    318338        class->get_url_string_func = tny_camel_msg_get_url_string_default; 
     339        class->uncache_attachments_func = tny_camel_msg_uncache_attachments_default; 
    319340 
    320341        object_class->finalize = tny_camel_msg_finalize; 
  • trunk/libtinymail-camel/tny-camel-msg.h

    r1717 r2267  
    5555        TnyFolder* (*get_folder_func) (TnyMsg *self); 
    5656        gchar* (*get_url_string_func) (TnyMsg *self); 
     57        void (*uncache_attachments_func) (TnyMsg *self); 
    5758}; 
    5859 
  • trunk/libtinymail/tny-folder-stats.c

    r1856 r2267  
    165165        if (priv->folder) 
    166166                g_object_unref (G_OBJECT (priv->folder)); 
     167        priv->folder = NULL; 
    167168 
    168169        (*parent_class->finalize) (object); 
  • trunk/libtinymail/tny-msg.c

    r1968 r2267  
    2828#include <tny-folder.h> 
    2929 
     30 
     31/** 
     32 * tny_msg_uncache_attachments: 
     33 * @self: a #TnyMsg object 
     34 *  
     35 * Uncache the attachments of @self. 
     36 *  
     37 **/ 
     38void  
     39tny_msg_uncache_attachments (TnyMsg *self) 
     40{ 
     41#ifdef DBC /* require */ 
     42        g_assert (TNY_IS_MSG (self)); 
     43        g_assert (TNY_MSG_GET_IFACE (self)->uncache_attachments_func != NULL); 
     44#endif 
     45 
     46        TNY_MSG_GET_IFACE (self)->uncache_attachments_func (self); 
     47 
     48#ifdef DBC /* ensure */ 
     49#endif 
     50 
     51        return; 
     52} 
    3053 
    3154/** 
  • trunk/libtinymail/tny-msg.h

    r1717 r2267  
    4646        TnyFolder* (*get_folder_func) (TnyMsg *self); 
    4747        gchar* (*get_url_string_func) (TnyMsg *self); 
     48        void (*uncache_attachments_func) (TnyMsg *self); 
    4849 
    4950}; 
     
    5455TnyFolder* tny_msg_get_folder (TnyMsg *self); 
    5556gchar* tny_msg_get_url_string (TnyMsg *self); 
     57void tny_msg_uncache_attachments (TnyMsg *self); 
    5658 
    5759G_END_DECLS 
  • trunk/tests/c-demo/tny-demoui-summary-view.c

    r2206 r2267  
    600600        } 
    601601 
     602 
     603 
     604        if (event->keyval == GDK_End) 
     605        { 
     606                GtkTreeSelection *selection = gtk_tree_view_get_selection (header_view); 
     607                GtkTreeModel *model; 
     608                GtkTreeIter iter; 
     609 
     610                if (gtk_tree_selection_get_selected (selection, &model, &iter)) 
     611                { 
     612                        TnyHeader *header; 
     613 
     614                        gtk_tree_model_get (model, &iter,  
     615                                TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN,  
     616                                &header, -1); 
     617 
     618                        if (header) 
     619                        { 
     620                                GtkWidget *dialog = gtk_message_dialog_new (NULL,  
     621                                        GTK_DIALOG_MODAL, 
     622                                        GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO,  
     623                                        _("This will uncache the message with subject \"%s\""), 
     624                                        tny_header_get_subject (header)); 
     625 
     626                                if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES) 
     627                                { 
     628                                        TnyFolder *folder; 
     629                                        TnyMsg *msg; 
     630 
     631                                        folder = tny_header_get_folder (header); 
     632                                        msg = tny_folder_get_msg (folder, header, NULL); 
     633                                        if (msg) { 
     634                                                tny_msg_uncache_attachments (msg); 
     635                                                g_object_unref (msg); 
     636                                        } 
     637                                        g_object_unref (folder); 
     638                                } 
     639 
     640                                gtk_widget_destroy (dialog); 
     641                                g_object_unref (G_OBJECT (header)); 
     642                        } 
     643                } 
     644                 
     645        } 
     646 
    602647        return; 
    603648}