1.1 --- a/imiptools/handlers/__init__.py Sat Jul 25 19:29:44 2015 +0200
1.2 +++ b/imiptools/handlers/__init__.py Sat Jul 25 23:18:58 2015 +0200
1.3 @@ -19,18 +19,15 @@
1.4 this program. If not, see <http://www.gnu.org/licenses/>.
1.5 """
1.6
1.7 -from datetime import datetime
1.8 from email.mime.text import MIMEText
1.9 -from imiptools.client import Client
1.10 +from imiptools.client import ClientForObject
1.11 from imiptools.config import MANAGER_PATH, MANAGER_URL
1.12 -from imiptools.data import Object, \
1.13 - get_address, get_uri, get_value, \
1.14 +from imiptools.data import Object, get_address, get_uri, \
1.15 is_new_object, uri_dict, uri_item, uri_values
1.16 from imiptools.dates import format_datetime, get_recurrence_start_point, \
1.17 to_timezone
1.18 from imiptools.period import can_schedule, remove_period, \
1.19 - remove_additional_periods, remove_affected_period, \
1.20 - update_freebusy
1.21 + remove_additional_periods, remove_affected_period
1.22 from imiptools.profile import Preferences
1.23 from socket import gethostname
1.24 import imip_store
1.25 @@ -47,7 +44,7 @@
1.26 recurrenceid and "/%s" % recurrenceid or ""
1.27 )
1.28
1.29 -class Handler(Client):
1.30 +class Handler(ClientForObject):
1.31
1.32 "General handler support."
1.33
1.34 @@ -55,28 +52,24 @@
1.35 publisher=None):
1.36
1.37 """
1.38 - Initialise the handler with the calendar 'obj' and the 'senders' and
1.39 - 'recipient' of the object (if specifically indicated).
1.40 + Initialise the handler with any specifically indicated 'senders' and
1.41 + 'recipient' of a calendar object. The object is initially undefined.
1.42 +
1.43 + The optional 'messenger' provides a means of interacting with the mail
1.44 + system.
1.45
1.46 The optional 'store' and 'publisher' can be specified to override the
1.47 default store and publisher objects.
1.48 """
1.49
1.50 - Client.__init__(self, recipient and get_uri(recipient))
1.51 + ClientForObject.__init__(self, None, recipient and get_uri(recipient), messenger)
1.52
1.53 self.senders = senders and set(map(get_address, senders))
1.54 self.recipient = recipient and get_address(recipient)
1.55 - self.messenger = messenger
1.56
1.57 self.results = []
1.58 self.outgoing_methods = set()
1.59
1.60 - self.obj = None
1.61 - self.uid = None
1.62 - self.recurrenceid = None
1.63 - self.sequence = None
1.64 - self.dtstamp = None
1.65 -
1.66 self.store = store or imip_store.FileStore()
1.67
1.68 try:
1.69 @@ -84,13 +77,6 @@
1.70 except OSError:
1.71 self.publisher = None
1.72
1.73 - def set_object(self, obj):
1.74 - self.obj = obj
1.75 - self.uid = self.obj.get_uid()
1.76 - self.recurrenceid = self.obj.get_recurrenceid()
1.77 - self.sequence = self.obj.get_value("SEQUENCE")
1.78 - self.dtstamp = self.obj.get_value("DTSTAMP")
1.79 -
1.80 def wrap(self, text, link=True):
1.81
1.82 "Wrap any valid message for passing to the recipient."
1.83 @@ -164,51 +150,6 @@
1.84 recurrenceid = self.get_recurrence_start_point(recurrenceid)
1.85 remove_affected_period(freebusy, self.uid, recurrenceid)
1.86
1.87 - def _update_freebusy(self, freebusy, periods, recurrenceid, transp=None):
1.88 -
1.89 - """
1.90 - Update the 'freebusy' collection with the given 'periods', indicating an
1.91 - explicit 'recurrenceid' to affect either a recurrence or the parent
1.92 - event.
1.93 - """
1.94 -
1.95 - update_freebusy(freebusy, periods,
1.96 - transp or self.obj.get_value("TRANSP") or "OPAQUE",
1.97 - self.uid, recurrenceid,
1.98 - self.obj.get_value("SUMMARY"),
1.99 - self.obj.get_value("ORGANIZER"))
1.100 -
1.101 - def update_freebusy(self, freebusy, periods, transp=None):
1.102 -
1.103 - """
1.104 - Update the 'freebusy' collection for this event with the given
1.105 - 'periods'.
1.106 - """
1.107 -
1.108 - self._update_freebusy(freebusy, periods, self.recurrenceid, transp)
1.109 -
1.110 - def update_freebusy_for_participant(self, freebusy, periods, attr, for_organiser=False):
1.111 -
1.112 - """
1.113 - Update the 'freebusy' collection using the given 'periods', subject to
1.114 - the 'attr' provided for the participant, indicating whether this is
1.115 - being generated 'for_organiser' or not.
1.116 - """
1.117 -
1.118 - # Organisers employ a special transparency if not attending.
1.119 -
1.120 - if self.is_participating(attr, for_organiser):
1.121 - self.update_freebusy(freebusy, periods,
1.122 - transp=self.get_overriding_transparency(attr, for_organiser))
1.123 - else:
1.124 - self.remove_from_freebusy(freebusy)
1.125 -
1.126 - def is_participating(self, attr, as_organiser=False):
1.127 - return as_organiser or not attr or attr.get("PARTSTAT") != "DECLINED"
1.128 -
1.129 - def get_overriding_transparency(self, attr, as_organiser=False):
1.130 - return as_organiser and not (attr and attr.get("PARTSTAT")) and "ORG" or None
1.131 -
1.132 # Convenience methods for updating stored free/busy information.
1.133
1.134 def update_freebusy_from_participant(self, participant_item, for_organiser):
1.135 @@ -523,19 +464,4 @@
1.136
1.137 return True
1.138
1.139 - def update_dtstamp(self):
1.140 -
1.141 - "Update the DTSTAMP in the current object."
1.142 -
1.143 - dtstamp = self.obj.get_utc_datetime("DTSTAMP")
1.144 - utcnow = to_timezone(datetime.utcnow(), "UTC")
1.145 - self.obj["DTSTAMP"] = [(format_datetime(dtstamp > utcnow and dtstamp or utcnow), {})]
1.146 -
1.147 - def set_sequence(self, increment=False):
1.148 -
1.149 - "Update the SEQUENCE in the current object."
1.150 -
1.151 - sequence = self.obj.get_value("SEQUENCE") or "0"
1.152 - self.obj["SEQUENCE"] = [(str(int(sequence) + (increment and 1 or 0)), {})]
1.153 -
1.154 # vim: tabstop=4 expandtab shiftwidth=4