2002-06-21 06:04:47 +02:00
|
|
|
# Local status cache virtual folder
|
2008-03-03 19:57:56 +01:00
|
|
|
# Copyright (C) 2002 - 2008 John Goerzen
|
2002-06-21 06:04:47 +02:00
|
|
|
# <jgoerzen@complete.org>
|
|
|
|
#
|
|
|
|
# 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
|
2003-04-16 21:23:45 +02:00
|
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
|
|
# (at your option) any later version.
|
2002-06-21 06:04:47 +02:00
|
|
|
#
|
|
|
|
# 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
|
2006-08-12 06:15:55 +02:00
|
|
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
2002-06-21 06:04:47 +02:00
|
|
|
|
|
|
|
from Base import BaseFolder
|
2003-01-03 08:01:41 +01:00
|
|
|
import os, threading
|
2002-06-21 06:04:47 +02:00
|
|
|
|
2002-06-21 12:01:10 +02:00
|
|
|
magicline = "OFFLINEIMAP LocalStatus CACHE DATA - DO NOT MODIFY - FORMAT 1"
|
2002-06-21 06:04:47 +02:00
|
|
|
|
|
|
|
class LocalStatusFolder(BaseFolder):
|
2008-08-02 21:55:08 +02:00
|
|
|
def __init__(self, root, name, repository, accountname, config):
|
2002-06-21 06:04:47 +02:00
|
|
|
self.name = name
|
|
|
|
self.root = root
|
|
|
|
self.sep = '.'
|
2008-08-02 21:55:08 +02:00
|
|
|
self.config = config
|
2008-08-02 22:11:23 +02:00
|
|
|
self.dofsync = config.getdefaultboolean("general", "fsync", True)
|
2002-06-21 06:04:47 +02:00
|
|
|
self.filename = os.path.join(root, name)
|
2003-04-18 04:18:34 +02:00
|
|
|
self.filename = repository.getfolderfilename(name)
|
2002-06-21 06:04:47 +02:00
|
|
|
self.messagelist = None
|
2002-08-20 22:54:02 +02:00
|
|
|
self.repository = repository
|
2003-01-03 08:01:41 +01:00
|
|
|
self.savelock = threading.Lock()
|
|
|
|
self.doautosave = 1
|
2003-01-06 00:07:58 +01:00
|
|
|
self.accountname = accountname
|
2003-04-18 04:18:34 +02:00
|
|
|
BaseFolder.__init__(self)
|
2003-01-06 00:07:58 +01:00
|
|
|
|
|
|
|
def getaccountname(self):
|
|
|
|
return self.accountname
|
2002-06-21 06:04:47 +02:00
|
|
|
|
2002-07-16 04:26:58 +02:00
|
|
|
def storesmessages(self):
|
|
|
|
return 0
|
|
|
|
|
2002-06-21 06:04:47 +02:00
|
|
|
def isnewfolder(self):
|
|
|
|
return not os.path.exists(self.filename)
|
|
|
|
|
|
|
|
def getname(self):
|
|
|
|
return self.name
|
|
|
|
|
|
|
|
def getroot(self):
|
|
|
|
return self.root
|
|
|
|
|
|
|
|
def getsep(self):
|
|
|
|
return self.sep
|
|
|
|
|
|
|
|
def getfullname(self):
|
|
|
|
return self.filename
|
|
|
|
|
2002-08-08 04:20:36 +02:00
|
|
|
def deletemessagelist(self):
|
|
|
|
if not self.isnewfolder():
|
|
|
|
os.unlink(self.filename)
|
|
|
|
|
2002-06-21 06:04:47 +02:00
|
|
|
def cachemessagelist(self):
|
|
|
|
if self.isnewfolder():
|
|
|
|
self.messagelist = {}
|
|
|
|
return
|
|
|
|
file = open(self.filename, "rt")
|
|
|
|
self.messagelist = {}
|
|
|
|
line = file.readline().strip()
|
2008-03-20 13:46:42 +01:00
|
|
|
if not line and not line.read():
|
2008-03-20 13:15:37 +01:00
|
|
|
# The status file is empty - should not have happened,
|
|
|
|
# but somehow did.
|
|
|
|
file.close()
|
|
|
|
return
|
2002-06-21 06:04:47 +02:00
|
|
|
assert(line == magicline)
|
|
|
|
for line in file.xreadlines():
|
2002-06-21 06:30:08 +02:00
|
|
|
line = line.strip()
|
2011-05-04 19:44:01 +02:00
|
|
|
try:
|
|
|
|
uid, flags = line.split(':')
|
|
|
|
uid = long(uid)
|
|
|
|
except ValueError, e:
|
|
|
|
errstr = "Corrupt line '%s' in cache file '%s'" % (line, self.filename)
|
|
|
|
self.ui.warn(errstr)
|
|
|
|
raise ValueError(errstr)
|
2002-06-21 06:04:47 +02:00
|
|
|
flags = [x for x in flags]
|
|
|
|
self.messagelist[uid] = {'uid': uid, 'flags': flags}
|
|
|
|
file.close()
|
|
|
|
|
2003-01-03 08:01:41 +01:00
|
|
|
def autosave(self):
|
|
|
|
if self.doautosave:
|
|
|
|
self.save()
|
|
|
|
|
2002-06-21 06:04:47 +02:00
|
|
|
def save(self):
|
2003-01-03 08:01:41 +01:00
|
|
|
self.savelock.acquire()
|
|
|
|
try:
|
|
|
|
file = open(self.filename + ".tmp", "wt")
|
|
|
|
file.write(magicline + "\n")
|
|
|
|
for msg in self.messagelist.values():
|
|
|
|
flags = msg['flags']
|
|
|
|
flags.sort()
|
|
|
|
flags = ''.join(flags)
|
|
|
|
file.write("%s:%s\n" % (msg['uid'], flags))
|
2007-03-28 22:23:18 +02:00
|
|
|
file.flush()
|
2008-08-02 21:55:08 +02:00
|
|
|
if self.dofsync:
|
|
|
|
os.fsync(file.fileno())
|
2003-01-03 08:01:41 +01:00
|
|
|
file.close()
|
|
|
|
os.rename(self.filename + ".tmp", self.filename)
|
2007-03-28 22:23:18 +02:00
|
|
|
|
2008-08-02 21:55:08 +02:00
|
|
|
if self.dofsync:
|
2011-01-12 11:15:10 +01:00
|
|
|
fd = os.open(os.path.dirname(self.filename), os.O_RDONLY)
|
|
|
|
os.fsync(fd)
|
|
|
|
os.close(fd)
|
2007-03-28 22:23:18 +02:00
|
|
|
|
2003-01-03 08:01:41 +01:00
|
|
|
finally:
|
|
|
|
self.savelock.release()
|
2002-06-21 06:04:47 +02:00
|
|
|
|
|
|
|
def getmessagelist(self):
|
|
|
|
return self.messagelist
|
|
|
|
|
2006-08-22 03:09:36 +02:00
|
|
|
def savemessage(self, uid, content, flags, rtime):
|
2002-06-21 06:04:47 +02:00
|
|
|
if uid < 0:
|
|
|
|
# We cannot assign a uid.
|
|
|
|
return uid
|
|
|
|
|
|
|
|
if uid in self.messagelist: # already have it
|
|
|
|
self.savemessageflags(uid, flags)
|
|
|
|
return uid
|
|
|
|
|
2006-08-22 03:09:36 +02:00
|
|
|
self.messagelist[uid] = {'uid': uid, 'flags': flags, 'time': rtime}
|
2003-01-03 08:01:41 +01:00
|
|
|
self.autosave()
|
2002-06-21 06:04:47 +02:00
|
|
|
return uid
|
|
|
|
|
|
|
|
def getmessageflags(self, uid):
|
|
|
|
return self.messagelist[uid]['flags']
|
|
|
|
|
2006-08-22 03:09:36 +02:00
|
|
|
def getmessagetime(self, uid):
|
|
|
|
return self.messagelist[uid]['time']
|
|
|
|
|
2002-06-21 06:04:47 +02:00
|
|
|
def savemessageflags(self, uid, flags):
|
|
|
|
self.messagelist[uid]['flags'] = flags
|
2003-01-03 08:01:41 +01:00
|
|
|
self.autosave()
|
2002-06-21 06:04:47 +02:00
|
|
|
|
|
|
|
def deletemessage(self, uid):
|
2010-03-27 16:18:25 +01:00
|
|
|
self.deletemessages([uid])
|
|
|
|
|
|
|
|
def deletemessages(self, uidlist):
|
|
|
|
# Weed out ones not in self.messagelist
|
|
|
|
uidlist = [uid for uid in uidlist if uid in self.messagelist]
|
|
|
|
if not len(uidlist):
|
2002-06-21 06:30:08 +02:00
|
|
|
return
|
2010-03-27 16:18:25 +01:00
|
|
|
|
|
|
|
for uid in uidlist:
|
|
|
|
del(self.messagelist[uid])
|
2003-01-03 08:01:41 +01:00
|
|
|
self.autosave()
|