learn to not delete messages
This enables the "append" mode feature. Configuration option is sync_deletes in both local and remote repositories. Marked EXPERIMENTAL and UNTESTED. Signed-off-by: Nicolas Sebrecht <nicolas.s-dev@laposte.net>
This commit is contained in:
		@@ -428,6 +428,7 @@ remoterepository = RemoteExample
 | 
				
			|||||||
#
 | 
					#
 | 
				
			||||||
#proxy = SOCKS5:IP:9999
 | 
					#proxy = SOCKS5:IP:9999
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[Repository LocalExample]
 | 
					[Repository LocalExample]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Each repository requires a "type" declaration. The types supported for
 | 
					# Each repository requires a "type" declaration. The types supported for
 | 
				
			||||||
@@ -473,6 +474,14 @@ localfolders = ~/Test
 | 
				
			|||||||
#startdate = 2015-04-01
 | 
					#startdate = 2015-04-01
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This option stands in the [Repository LocalExample] section.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Remove messages on remote when deleted in local. Default is yes.
 | 
				
			||||||
 | 
					# This feature is EXPERIMENTAL and UNTESTED.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#sync_deletes = yes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# This option stands in the [Repository LocalExample] section.
 | 
					# This option stands in the [Repository LocalExample] section.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Some users may not want the atime (last access time) of folders to be
 | 
					# Some users may not want the atime (last access time) of folders to be
 | 
				
			||||||
@@ -1069,6 +1078,14 @@ remoteuser = username
 | 
				
			|||||||
#createfolders = True
 | 
					#createfolders = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This option stands in the [Repository RemoteExample] section.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Remove messages in local when deleted on remote. Default is yes.
 | 
				
			||||||
 | 
					# This feature is EXPERIMENTAL and UNTESTED.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					#sync_deletes = yes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# This option stands in the [Repository RemoteExample] section.
 | 
					# This option stands in the [Repository RemoteExample] section.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# 'foldersort' determines how folders are sorted.
 | 
					# 'foldersort' determines how folders are sorted.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,24 +54,29 @@ class BaseFolder(object):
 | 
				
			|||||||
        if self.visiblename == self.getsep():
 | 
					        if self.visiblename == self.getsep():
 | 
				
			||||||
            self.visiblename = ''
 | 
					            self.visiblename = ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        repoconfname = "Repository " + repository.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.config = repository.getconfig()
 | 
					        self.config = repository.getconfig()
 | 
				
			||||||
        utime_from_header_global = self.config.getdefaultboolean(
 | 
					        utime_from_header_global = self.config.getdefaultboolean(
 | 
				
			||||||
            "general", "utime_from_header", False)
 | 
					            "general", "utime_from_header", False)
 | 
				
			||||||
        repo = "Repository " + repository.name
 | 
					        self._utime_from_header = self.config.getdefaultboolean(
 | 
				
			||||||
        self._utime_from_header = self.config.getdefaultboolean(repo,
 | 
					            repoconfname, "utime_from_header", utime_from_header_global)
 | 
				
			||||||
            "utime_from_header", utime_from_header_global)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Do we need to use mail timestamp for filename prefix?
 | 
					        # Do we need to use mail timestamp for filename prefix?
 | 
				
			||||||
        filename_use_mail_timestamp_global = self.config.getdefaultboolean(
 | 
					        filename_use_mail_timestamp_global = self.config.getdefaultboolean(
 | 
				
			||||||
            "general", "filename_use_mail_timestamp", False)
 | 
					            "general", "filename_use_mail_timestamp", False)
 | 
				
			||||||
        repo = "Repository " + repository.name
 | 
					        self._filename_use_mail_timestamp = self.config.getdefaultboolean(
 | 
				
			||||||
        self._filename_use_mail_timestamp = self.config.getdefaultboolean(repo,
 | 
					            repoconfname,
 | 
				
			||||||
            "filename_use_mail_timestamp", filename_use_mail_timestamp_global)
 | 
					            "filename_use_mail_timestamp",
 | 
				
			||||||
 | 
					            filename_use_mail_timestamp_global)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self._sync_deletes = self.config.getdefaultboolean(
 | 
				
			||||||
 | 
					            repoconfname, "sync_deletes", True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Determine if we're running static or dynamic folder filtering
 | 
					        # Determine if we're running static or dynamic folder filtering
 | 
				
			||||||
        # and check filtering status
 | 
					        # and check filtering status
 | 
				
			||||||
        self._dynamic_folderfilter = self.config.getdefaultboolean(
 | 
					        self._dynamic_folderfilter = self.config.getdefaultboolean(
 | 
				
			||||||
            repo, "dynamic_folderfilter", False)
 | 
					            repoconfname, "dynamic_folderfilter", False)
 | 
				
			||||||
        self._sync_this = repository.should_sync_folder(self.ffilter_name)
 | 
					        self._sync_this = repository.should_sync_folder(self.ffilter_name)
 | 
				
			||||||
        if self._dynamic_folderfilter:
 | 
					        if self._dynamic_folderfilter:
 | 
				
			||||||
            self.ui.debug('', "Running dynamic folder filtering on '%s'[%s]"%
 | 
					            self.ui.debug('', "Running dynamic folder filtering on '%s'[%s]"%
 | 
				
			||||||
@@ -81,9 +86,11 @@ class BaseFolder(object):
 | 
				
			|||||||
                (self.ffilter_name, repository))
 | 
					                (self.ffilter_name, repository))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Passes for syncmessagesto
 | 
					        # Passes for syncmessagesto
 | 
				
			||||||
        self.syncmessagesto_passes = [('copying messages'       , self.__syncmessagesto_copy),
 | 
					        self.syncmessagesto_passes = [
 | 
				
			||||||
                                      ('deleting messages'      , self.__syncmessagesto_delete),
 | 
					            ('copying messages'       , self.__syncmessagesto_copy),
 | 
				
			||||||
                                      ('syncing flags'          , self.__syncmessagesto_flags)]
 | 
					            ('deleting messages'      , self.__syncmessagesto_delete),
 | 
				
			||||||
 | 
					            ('syncing flags'          , self.__syncmessagesto_flags)
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def getname(self):
 | 
					    def getname(self):
 | 
				
			||||||
        """Returns name"""
 | 
					        """Returns name"""
 | 
				
			||||||
@@ -756,7 +763,7 @@ class BaseFolder(object):
 | 
				
			|||||||
        for uid in uidlist:
 | 
					        for uid in uidlist:
 | 
				
			||||||
            self.deletemessage(uid)
 | 
					            self.deletemessage(uid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def copymessageto(self, uid, dstfolder, statusfolder, register = 1):
 | 
					    def copymessageto(self, uid, dstfolder, statusfolder, register=1):
 | 
				
			||||||
        """Copies a message from self to dst if needed, updating the status
 | 
					        """Copies a message from self to dst if needed, updating the status
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Note that this function does not check against dryrun settings,
 | 
					        Note that this function does not check against dryrun settings,
 | 
				
			||||||
@@ -873,8 +880,7 @@ class BaseFolder(object):
 | 
				
			|||||||
                thread.start()
 | 
					                thread.start()
 | 
				
			||||||
                threads.append(thread)
 | 
					                threads.append(thread)
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                self.copymessageto(uid, dstfolder, statusfolder,
 | 
					                self.copymessageto(uid, dstfolder, statusfolder, register=0)
 | 
				
			||||||
                                   register = 0)
 | 
					 | 
				
			||||||
        for thread in threads:
 | 
					        for thread in threads:
 | 
				
			||||||
            thread.join()
 | 
					            thread.join()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -886,15 +892,20 @@ class BaseFolder(object):
 | 
				
			|||||||
    def __syncmessagesto_delete(self, dstfolder, statusfolder):
 | 
					    def __syncmessagesto_delete(self, dstfolder, statusfolder):
 | 
				
			||||||
        """Pass 2: Remove locally deleted messages on dst.
 | 
					        """Pass 2: Remove locally deleted messages on dst.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Get all UIDS in statusfolder but not self. These are messages
 | 
					        Get all UIDs in statusfolder but not self. These are messages
 | 
				
			||||||
        that were deleted in 'self'. Delete those from dstfolder and
 | 
					        that were deleted in 'self'. Delete those from dstfolder and
 | 
				
			||||||
        statusfolder.
 | 
					        statusfolder.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        This function checks and protects us from action in dryrun mode.
 | 
					        This function checks and protects us from action in dryrun mode.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
 | 
					        # The list of messages to delete. If sync of deletions is disabled we
 | 
				
			||||||
 | 
					        # still remove stale entries from statusfolder (neither in local nor
 | 
				
			||||||
 | 
					        # remote).
 | 
				
			||||||
 | 
					        deletelist = filter(
 | 
				
			||||||
 | 
					                lambda uid: uid >= 0 and not self.uidexists(uid)
 | 
				
			||||||
 | 
					                    and (self._sync_deletes or not dstfolder.uidexists(uid)),
 | 
				
			||||||
 | 
					                statusfolder.getmessageuidlist())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        deletelist = filter(lambda uid: uid >= 0 and not
 | 
					 | 
				
			||||||
            self.uidexists(uid), statusfolder.getmessageuidlist())
 | 
					 | 
				
			||||||
        if len(deletelist):
 | 
					        if len(deletelist):
 | 
				
			||||||
            # Delete in statusfolder first to play safe. In case of abort, we
 | 
					            # Delete in statusfolder first to play safe. In case of abort, we
 | 
				
			||||||
            # won't lose message, we will just unneccessarily retransmit some.
 | 
					            # won't lose message, we will just unneccessarily retransmit some.
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user