Script also works with python 2.7
[imap-fix-internaldate] / src / mailbox_state.py
1 '''
2 mailbox_state.py - The module contains the MailboxState class.
3
4 Copyright (c) 2012 Intra2net AG
5 Author: Plamen Dimitrov
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 '''
17
18 class MailboxState:
19     """This class is responsible for containing and updating a mailbox data."""
20
21     # class attributes
22     # string with quotation marks for the mailbox name
23     name = None
24     # string for the mailbox uidvalidity
25     uidvalidity = None
26     # string for user owning the mailbox
27     owner = None
28     # list of bytes for last cached mail uids
29     uids = None
30     # tolerance with which the mailbox was synced
31     tolerance = None
32     # boolean flag for committing state changes
33     needs_save = None
34     # integer for found date conflicts
35     date_conflicts = None
36     # integer for found messages with missing received headers
37     no_received_field = None
38     # unique key for a mailbox
39     key = None
40
41     def __init__(self, name, uidvalidity, owner):
42         self.name = name
43         self.uidvalidity = uidvalidity
44         self.owner = owner
45
46         self.uids = []
47         self.tolerance = 0
48         self.needs_save = False
49
50         self.date_conflicts = 0
51         self.no_received_field = 0
52
53         #special key to ensure better mailbox uniqueness
54         self.key = self.name.strip('"') + self.uidvalidity
55
56         return
57
58     def __getstate__(self):
59         """Prepares the MailboxState instance for pickling."""
60         changed_dict = self.__dict__.copy()
61         # remove the following attributes for pickling
62         del changed_dict['needs_save']
63         del changed_dict['date_conflicts']
64         del changed_dict['no_received_field']
65         return changed_dict
66
67     def __setstate__(self, state):
68         """Prepares the MailboxState instance for unpickling."""
69         self.name = state["name"]
70         self.uidvalidity = state["uidvalidity"]
71         self.owner = state["owner"]
72
73         self.uids = state["uids"]
74         self.tolerance = state["tolerance"]
75         self.needs_save = False
76
77         self.date_conflicts = 0
78         self.no_received_field = 0
79         
80         self.key = state["key"]
81         
82         return    
83
84     def __str__(self):
85         """Makes the class printable."""
86         return self.key
87
88     def synchronize(self, list_ids, tolerance):
89         """Adds new messages to the cache and returns a list of them.
90         Confirm the changes to a mailbox to finally save it."""
91         new_ids = []
92         # cache is invalid if mailbox is synced with different tolerance
93         if(len(self.uids)==0 or tolerance != self.tolerance):
94             new_ids = list_ids
95             self.tolerance = tolerance
96         else:
97             for uid in list_ids:
98                 try:
99                     self.uids.index(uid)
100                 except ValueError:
101                     new_ids.append(uid)
102         # update this mailbox potential uids
103         self.uids = list_ids
104         return new_ids
105
106     def confirm_change(self):
107         """Confirm the chages to the cached mailbox and specify used tolerance."""
108         self.needs_save = True
109         return