imip-agent

tests/test_handle.py

1061:5f9f96eb4f8f
2016-02-09 Paul Boddie Updated the administration page, removing obsolete settings references.
     1 #!/usr/bin/env python     2      3 """     4 A handler to help with testing.     5      6 Copyright (C) 2014, 2015, 2016 Paul Boddie <paul@boddie.org.uk>     7      8 This program is free software; you can redistribute it and/or modify it under     9 the terms of the GNU General Public License as published by the Free Software    10 Foundation; either version 3 of the License, or (at your option) any later    11 version.    12     13 This program is distributed in the hope that it will be useful, but WITHOUT    14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS    15 FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more    16 details.    17     18 You should have received a copy of the GNU General Public License along with    19 this program.  If not, see <http://www.gnu.org/licenses/>.    20 """    21     22 from imiptools.client import ClientForObject    23 from imiptools.data import Object, get_address, parse_object    24 from imiptools.dates import get_datetime, to_timezone    25 from imiptools.mail import Messenger    26 from imiptools.period import RecurringPeriod    27 import imip_store    28 import sys    29     30 class TestClient(ClientForObject):    31     32     """    33     A content handler for use in testing, as opposed to operating within the    34     mail processing pipeline.    35     """    36     37     # Action methods.    38     39     def handle_request(self, action, start=None, end=None):    40     41         """    42         Process the current request for the current user. Return whether the    43         given 'action' was taken.    44     45         If 'start' and 'end' are specified, they will be used in any    46         counter-proposal.    47         """    48     49         # Reply only on behalf of this user.    50     51         if action in ("accept", "decline"):    52             attendee_attr = self.update_participation(action == "accept" and "ACCEPTED" or "DECLINED")    53             method = "REPLY"    54     55         # For counter-proposals, set a new main period for the event.    56     57         elif action == "counter":    58             attendee_attr = self.obj.get_value_map("ATTENDEE").get(self.user)    59             period = self.obj.get_main_period(self.get_tzid())    60     61             # Use the existing or configured time zone for the specified    62             # datetimes.    63     64             start = to_timezone(get_datetime(start), period.tzid)    65             end = to_timezone(get_datetime(end), period.tzid)    66             period = RecurringPeriod(start, end, period.tzid, period.origin, period.get_start_attr(), period.get_end_attr())    67             self.obj.set_period(period)    68             method = "COUNTER"    69         else:    70             return None    71     72         if not attendee_attr:    73             return None    74     75         # NOTE: This is a simpler form of the code in imipweb.client.    76     77         organiser = get_address(self.obj.get_value("ORGANIZER"))    78     79         self.update_sender(attendee_attr)    80         self.obj["ATTENDEE"] = [(self.user, attendee_attr)]    81         self.update_dtstamp()    82         self.update_sequence(False)    83     84         message = self.messenger.make_outgoing_message(    85             [self.obj.to_part(method)],    86             [organiser],    87             outgoing_bcc=get_address(self.user)    88             )    89     90         return message.as_string()    91     92 # A simple main program that attempts to handle a stored request, writing the    93 # response message to standard output.    94     95 if __name__ == "__main__":    96     try:    97         action, store_dir, journal_dir, preferences_dir, user = sys.argv[1:6]    98         if action == "counter":    99             start, end = sys.argv[6:8]   100             i = 8   101         else:   102             start, end = None, None   103             i = 6   104         uid, recurrenceid = (sys.argv[i:i+2] + [None] * 2)[:2]   105     except ValueError:   106         print >>sys.stderr, """\   107 Need 'accept', 'counter' or 'decline', a store directory, a preferences   108 directory, user URI, any counter-proposal datetimes (see below), plus the   109 appropriate event UID and RECURRENCE-ID (if a recurrence is involved).   110    111 The RECURRENCE-ID must be in exactly the form employed by the store, not a   112 different but equivalent representation.   113    114 Alternatively, omit the UID and RECURRENCE-ID and provide event-only details on   115 standard input to force the script to handle an event not already present in the   116 store.   117    118 If 'counter' has been indicated, alternative start and end datetimes are also   119 required.   120 """   121         sys.exit(1)   122    123     store = imip_store.FileStore(store_dir)   124     journal = imip_store.FileJournal(journal_dir)   125    126     if uid is not None:   127         fragment = store.get_event(user, uid, recurrenceid)   128    129         if not fragment:   130             print >>sys.stderr, "No such event:", uid, recurrenceid   131             sys.exit(1)   132     else:   133         fragment = parse_object(sys.stdin, "utf-8")   134    135     obj = Object(fragment)   136     handler = TestClient(obj, user, Messenger(), store, None, journal, preferences_dir)   137     response = handler.handle_request(action, start, end)   138    139     if response:   140         if uid is not None:   141             store.dequeue_request(user, uid, recurrenceid)   142         print response   143     else:   144         sys.exit(1)   145    146 # vim: tabstop=4 expandtab shiftwidth=4