''' caching_data.py - The module contains the CachingData class. Copyright (c) 2012 Intra2net AG Author: Plamen Dimitrov 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 the Free Software Foundation, either version 3 of the License, or (at your option) any later version. 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. ''' import os, tempfile import pickle from mailbox_state import MailboxState CACHING_FILENAME = "caching_data.dat" class CachingData: """This class is responsible for the caching of data.""" # class attributes # integer for version of the cache version = None # dictionary of usernames as keys and dictionaries as values # the second dictionaries have unique mailbox keys and mailboxes as values data = None def __init__(self): try: cachingfile = open(CACHING_FILENAME, 'rb') self.version, self.data = pickle.load(cachingfile) print("Cache version", self.version) print(len(self.data), "users found.") except IOError: self.version = 0 self.data = {} with open(CACHING_FILENAME, 'wb') as cachingfile: pickle.dump((0, self.data), cachingfile) def __del__(self): # create temporary file first location = os.path.dirname(CACHING_FILENAME) file_descriptor, tmpname = tempfile.mkstemp(dir=location) cachingfile = os.fdopen(file_descriptor, 'wb') # prepare data based on a save flag saved_data = {} for user in self.data: saved_data[user] = {} for box_key in self.data[user]: if(self.data[user][box_key].needs_save): saved_data[user][box_key] = self.data[user][box_key] print(saved_data[user][box_key].name, "will be saved.") if(len(saved_data[user])==0): del saved_data[user] print(user, "will not be saved.") self.data = saved_data # avoid test mode or cases where nothing needs saving if(len(saved_data)==0): os.unlink(tmpname) return # serialize in file self.version += 1 pickle.dump((self.version, self.data), cachingfile) print(len(self.data), "users stored.") cachingfile.close() os.rename(tmpname, CACHING_FILENAME) def retrieve_cached_mailbox(self, name, uidvalidity, user): """Retrieve a cached mailbox or create it.""" box_key = name.strip('"') + uidvalidity if(user not in self.data): self.data[user] = {} #print(user, "created.") if(box_key not in self.data[user]): self.data[user][box_key] = MailboxState(name, uidvalidity, user) #print(box_key, "created.") return self.data[user][box_key] def report_date_conflicts(self): """Write a date conflicts report in a file.""" with open("conflict_stats.txt", 'w') as statsfile: owner_total_conflicts = {} owner_total_missing = {} for user in self.data: owner_total_conflicts[user] = 0 owner_total_missing[user] = 0 for box_key in self.data[user]: owner_total_conflicts[user] += self.data[user][box_key].date_conflicts owner_total_missing[user] += self.data[user][box_key].no_received_field statsfile.write("Total date conflicts to be corrected in a mailbox {0} are {1}.\n"\ .format(self.data[user][box_key].name, self.data[user][box_key].date_conflicts)) statsfile.write("Total missing received headers in a mailbox {0} are {1}.\n"\ .format(self.data[user][box_key].name, self.data[user][box_key].no_received_field)) statsfile.write("Total date conflicts to be corrected for user {0} are {1}.\n\n"\ .format(user, owner_total_missing[user])) return