]>
code.delx.au - offlineimap/blob - head/offlineimap/folder/Base.py
2 # Copyright (C) 2002 John Goerzen
3 # <jgoerzen@complete.org>
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 2 of the License, or
8 # (at your option) any later version.
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.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 """Returns the root of the folder, in a folder-specific fashion."""
29 """Returns the separator for this folder type."""
32 def getfullname(self
):
34 return self
.getroot() + self
.getsep() + self
.getname()
38 def isuidvalidityok(self
, remotefolder
):
39 raise NotImplementedException
41 def getuidvalidity(self
):
42 raise NotImplementedException
44 def saveuidvalidity(self
, newval
):
45 raise NotImplementedException
47 def cachemessagelist(self
):
48 """Reads the message list from disk or network and stores it in
49 memory for later use. This list will not be re-read from disk or
50 memory unless this function is called again."""
51 raise NotImplementedException
53 def getmessagelist(self
):
54 """Gets the current message list.
55 You must call cachemessagelist() before calling this function!"""
56 raise NotImplementedException
58 def getmessage(self
, uid
):
59 """Returns the content of the specified message."""
60 raise NotImplementedException
62 def savemessage(self
, uid
, content
):
63 """Writes a new message, with the specified uid.
64 If the uid is < 0, the backend should assign a new uid and return it.
65 If the backend cannot assign a new uid, it returns the uid passed in.
66 IMAP backend should be the only one that can assign a new uid.
67 If the uid is < 0 and the backend cannot assign a new UID, it is
68 required to TAKE NO ACTION other than returning the uid passed in.
70 If the uid is > 0, the backend should set the uid to this, if it can.
71 It will return the uid assigned in any case.
73 raise NotImplementedException
75 def getmessageflags(self
, uid
):
76 """Returns the flags for the specified message."""
77 raise NotImplementedException
79 def savemessageflags(self
, uid
, flags
):
80 """Sets the specified message's flags to the given set."""
81 raise NotImplementedException
83 def addmessageflags(self
, uid
, flags
):
84 """Adds the specified flags to the message's flag set. If a given
85 flag is already present, it will not be duplicated."""
86 newflags
= self
.getmessageflags(uid
)
88 if not flag
in newflags
:
91 self
.savemessageflags(uid
, newflags
)
93 def deletemessageflags(self
, uid
, flags
):
94 """Removes each flag given from the message's flag set. If a given
95 flag is already removed, no action will be taken for that flag."""
96 newflags
= self
.getmessageflags(uid
)
101 self
.savemessageflags(uid
, newflags
)
103 def deletemessage(self
, uid
):
104 raise NotImplementedException
106 def syncmessagesto(self
, dest
, applyto
= None):
107 """Syncs messages in this folder to the destination.
108 If applyto is specified, it should be a list of folders (don't forget
109 to include dest!) to which all write actions should be applied.
110 It defaults to [dest] if not specified."""
114 # Pass 1 -- Look for messages in self with a negative uid.
115 # These are messages in Maildirs that were not added by us.
116 # Try to add them to the dests, and once that succeeds, get the
117 # UID, add it to the others for real, add it to local for real,
118 # and delete the fake one.
120 for uid
in self
.getmessagelist().keys():
125 message
= self
.getmessage(uid
)
126 flags
= self
.getmessageflags(uid
)
127 for tryappend
in applyto
:
128 successuid
= tryappend
.savemessage(uid
, message
)
130 tryappend
.savemessageflags(uid
, flags
)
131 successobject
= tryappend
134 if successobject
!= None:
135 # Copy the message to the other remote servers.
136 for appendserver
in [x
for x
in applyto
if x
!= successobject
]:
137 appendserver
.savemessage(successuid
, message
)
138 appendserver
.savemessageflags(successuid
, flags
)
139 # Copy it to its new name on the local server and delete
140 # the one without a UID.
141 self
.savemessage(successuid
, message
)
142 self
.savemessageflags(successuid
, flags
)
143 self
.deletemessage(uid
)
145 # Did not find any server to take this message. Delete
148 # Pass 2 -- Look for messages present in self but not in dest.
149 # If any, add them to dest.
151 for uid
in self
.getmessagelist().keys():
152 if uid
< 0: # Ignore messages that pass 1 missed.
154 if not uid
in dest
.getmessagelist():
155 message
= self
.getmessage(uid
)
156 flags
= self
.getmessageflags(uid
)
157 for object in applyto
:
158 object.savemessage(uid
, message
)
159 object.savemessageflags(uid
, flags
)
161 # Pass 3 -- Look for message present in dest but not in self.
162 # If any, delete them.
164 for uid
in dest
.getmessagelist().keys():
165 if not uid
in self
.getmessagelist():
166 for object in applyto
:
167 object.deletemessage(uid
)
169 # Now, the message lists should be identical wrt the uids present.
170 # (except for potential negative uids that couldn't be placed
173 # Pass 3 -- Look for any flag identity issues -- set dest messages
174 # to have the same flags that we have here.
176 for uid
in self
.getmessagelist().keys():
177 if uid
< 0: # Ignore messages missed by pass 1
179 selfflags
= self
.getmessageflags(uid
)
180 destflags
= dest
.getmessageflags(uid
)
182 addflags
= [x
for x
in selfflags
if x
not in destflags
]
184 for object in applyto
:
185 object.addmessageflags(addflags
)
187 delflags
= [x
for x
in destflags
if x
not in selfflags
]
189 for object in applyto
:
190 object.deletemessageflags(delflags
)