imip-agent

Annotated imiptools/stores/common.py

1119:97b5330fa753
2016-04-18 Paul Boddie Merged changes from the default branch. freebusy-collections
paul@1069 1
#!/usr/bin/env python
paul@1069 2
paul@1069 3
"""
paul@1069 4
General support for calendar data storage.
paul@1069 5
paul@1069 6
Copyright (C) 2014, 2015, 2016 Paul Boddie <paul@boddie.org.uk>
paul@1069 7
paul@1069 8
This program is free software; you can redistribute it and/or modify it under
paul@1069 9
the terms of the GNU General Public License as published by the Free Software
paul@1069 10
Foundation; either version 3 of the License, or (at your option) any later
paul@1069 11
version.
paul@1069 12
paul@1069 13
This program is distributed in the hope that it will be useful, but WITHOUT
paul@1069 14
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
paul@1069 15
FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
paul@1069 16
details.
paul@1069 17
paul@1069 18
You should have received a copy of the GNU General Public License along with
paul@1069 19
this program.  If not, see <http://www.gnu.org/licenses/>.
paul@1069 20
"""
paul@1069 21
paul@1089 22
from imiptools.dates import format_datetime, get_datetime
paul@1075 23
paul@1069 24
class StoreBase:
paul@1069 25
paul@1069 26
    "The core operations of a data store."
paul@1069 27
paul@1069 28
    # User discovery.
paul@1069 29
paul@1069 30
    def get_users(self):
paul@1069 31
paul@1069 32
        "Return a list of users."
paul@1069 33
paul@1069 34
        pass
paul@1069 35
paul@1069 36
    # Event and event metadata access.
paul@1069 37
paul@1069 38
    def get_events(self, user):
paul@1069 39
paul@1069 40
        "Return a list of event identifiers."
paul@1069 41
paul@1069 42
        pass
paul@1069 43
paul@1069 44
    def get_all_events(self, user):
paul@1069 45
paul@1069 46
        "Return a set of (uid, recurrenceid) tuples for all events."
paul@1069 47
paul@1069 48
        uids = self.get_events(user)
paul@1069 49
        if not uids:
paul@1069 50
            return set()
paul@1069 51
paul@1069 52
        all_events = set()
paul@1069 53
        for uid in uids:
paul@1069 54
            all_events.add((uid, None))
paul@1069 55
            all_events.update([(uid, recurrenceid) for recurrenceid in self.get_recurrences(user, uid)])
paul@1069 56
paul@1069 57
        return all_events
paul@1069 58
paul@1069 59
    def get_event(self, user, uid, recurrenceid=None, dirname=None):
paul@1069 60
paul@1069 61
        """
paul@1069 62
        Get the event for the given 'user' with the given 'uid'. If
paul@1069 63
        the optional 'recurrenceid' is specified, a specific instance or
paul@1069 64
        occurrence of an event is returned.
paul@1069 65
        """
paul@1069 66
paul@1069 67
        pass
paul@1069 68
paul@1069 69
    def get_complete_event(self, user, uid):
paul@1069 70
paul@1069 71
        "Get the event for the given 'user' with the given 'uid'."
paul@1069 72
paul@1069 73
        pass
paul@1069 74
paul@1069 75
    def set_event(self, user, uid, recurrenceid, node):
paul@1069 76
paul@1069 77
        """
paul@1069 78
        Set an event for 'user' having the given 'uid' and 'recurrenceid' (which
paul@1069 79
        if the latter is specified, a specific instance or occurrence of an
paul@1069 80
        event is referenced), using the given 'node' description.
paul@1069 81
        """
paul@1069 82
paul@1069 83
        if recurrenceid:
paul@1069 84
            return self.set_recurrence(user, uid, recurrenceid, node)
paul@1069 85
        else:
paul@1069 86
            return self.set_complete_event(user, uid, node)
paul@1069 87
paul@1069 88
    def set_complete_event(self, user, uid, node):
paul@1069 89
paul@1069 90
        "Set an event for 'user' having the given 'uid' and 'node'."
paul@1069 91
paul@1069 92
        pass
paul@1069 93
paul@1069 94
    def remove_event(self, user, uid, recurrenceid=None):
paul@1069 95
paul@1069 96
        """
paul@1069 97
        Remove an event for 'user' having the given 'uid'. If the optional
paul@1069 98
        'recurrenceid' is specified, a specific instance or occurrence of an
paul@1069 99
        event is removed.
paul@1069 100
        """
paul@1069 101
paul@1069 102
        if recurrenceid:
paul@1069 103
            return self.remove_recurrence(user, uid, recurrenceid)
paul@1069 104
        else:
paul@1069 105
            for recurrenceid in self.get_recurrences(user, uid) or []:
paul@1069 106
                self.remove_recurrence(user, uid, recurrenceid)
paul@1069 107
            return self.remove_complete_event(user, uid)
paul@1069 108
paul@1069 109
    def remove_complete_event(self, user, uid):
paul@1069 110
paul@1069 111
        "Remove an event for 'user' having the given 'uid'."
paul@1069 112
paul@1069 113
        self.remove_recurrences(user, uid)
paul@1069 114
        return self.remove_parent_event(user, uid)
paul@1069 115
paul@1069 116
    def remove_parent_event(self, user, uid):
paul@1069 117
paul@1069 118
        "Remove the parent event for 'user' having the given 'uid'."
paul@1069 119
paul@1069 120
        pass
paul@1069 121
paul@1069 122
    def get_recurrences(self, user, uid):
paul@1069 123
paul@1069 124
        """
paul@1069 125
        Get additional event instances for an event of the given 'user' with the
paul@1069 126
        indicated 'uid'. Both active and cancelled recurrences are returned.
paul@1069 127
        """
paul@1069 128
paul@1069 129
        return self.get_active_recurrences(user, uid) + self.get_cancelled_recurrences(user, uid)
paul@1069 130
paul@1069 131
    def get_active_recurrences(self, user, uid):
paul@1069 132
paul@1069 133
        """
paul@1069 134
        Get additional event instances for an event of the given 'user' with the
paul@1069 135
        indicated 'uid'. Cancelled recurrences are not returned.
paul@1069 136
        """
paul@1069 137
paul@1069 138
        pass
paul@1069 139
paul@1069 140
    def get_cancelled_recurrences(self, user, uid):
paul@1069 141
paul@1069 142
        """
paul@1069 143
        Get additional event instances for an event of the given 'user' with the
paul@1069 144
        indicated 'uid'. Only cancelled recurrences are returned.
paul@1069 145
        """
paul@1069 146
paul@1069 147
        pass
paul@1069 148
paul@1069 149
    def get_recurrence(self, user, uid, recurrenceid):
paul@1069 150
paul@1069 151
        """
paul@1069 152
        For the event of the given 'user' with the given 'uid', return the
paul@1069 153
        specific recurrence indicated by the 'recurrenceid'.
paul@1069 154
        """
paul@1069 155
paul@1069 156
        pass
paul@1069 157
paul@1069 158
    def set_recurrence(self, user, uid, recurrenceid, node):
paul@1069 159
paul@1069 160
        "Set an event for 'user' having the given 'uid' and 'node'."
paul@1069 161
paul@1069 162
        pass
paul@1069 163
paul@1069 164
    def remove_recurrence(self, user, uid, recurrenceid):
paul@1069 165
paul@1069 166
        """
paul@1069 167
        Remove a special recurrence from an event stored by 'user' having the
paul@1069 168
        given 'uid' and 'recurrenceid'.
paul@1069 169
        """
paul@1069 170
paul@1069 171
        pass
paul@1069 172
paul@1069 173
    def remove_recurrences(self, user, uid):
paul@1069 174
paul@1069 175
        """
paul@1069 176
        Remove all recurrences for an event stored by 'user' having the given
paul@1069 177
        'uid'.
paul@1069 178
        """
paul@1069 179
paul@1069 180
        for recurrenceid in self.get_recurrences(user, uid):
paul@1069 181
            self.remove_recurrence(user, uid, recurrenceid)
paul@1069 182
paul@1069 183
        return self.remove_recurrence_collection(user, uid)
paul@1069 184
paul@1069 185
    def remove_recurrence_collection(self, user, uid):
paul@1069 186
paul@1069 187
        """
paul@1069 188
        Remove the collection of recurrences stored by 'user' having the given
paul@1069 189
        'uid'.
paul@1069 190
        """
paul@1069 191
paul@1069 192
        pass
paul@1069 193
paul@1069 194
    # Free/busy period providers, upon extension of the free/busy records.
paul@1069 195
paul@1075 196
    def _get_freebusy_providers(self, user):
paul@1075 197
paul@1075 198
        """
paul@1075 199
        Return the free/busy providers for the given 'user'.
paul@1075 200
paul@1075 201
        This function returns any stored datetime and a list of providers as a
paul@1075 202
        2-tuple. Each provider is itself a (uid, recurrenceid) tuple.
paul@1075 203
        """
paul@1075 204
paul@1075 205
        pass
paul@1075 206
paul@1069 207
    def get_freebusy_providers(self, user, dt=None):
paul@1069 208
paul@1069 209
        """
paul@1069 210
        Return a set of uncancelled events of the form (uid, recurrenceid)
paul@1069 211
        providing free/busy details beyond the given datetime 'dt'.
paul@1069 212
paul@1069 213
        If 'dt' is not specified, all events previously found to provide
paul@1069 214
        details will be returned. Otherwise, if 'dt' is earlier than the
paul@1069 215
        datetime recorded for the known providers, None is returned, indicating
paul@1069 216
        that the list of providers must be recomputed.
paul@1069 217
paul@1069 218
        This function returns a list of (uid, recurrenceid) tuples upon success.
paul@1069 219
        """
paul@1069 220
paul@1075 221
        t = self._get_freebusy_providers(user)
paul@1075 222
        if not t:
paul@1075 223
            return None
paul@1075 224
paul@1075 225
        dt_string, t = t
paul@1075 226
paul@1075 227
        # If the requested datetime is earlier than the stated datetime, the
paul@1075 228
        # providers will need to be recomputed.
paul@1075 229
paul@1075 230
        if dt:
paul@1075 231
            providers_dt = get_datetime(dt_string)
paul@1075 232
            if not providers_dt or providers_dt > dt:
paul@1075 233
                return None
paul@1075 234
paul@1075 235
        # Otherwise, return the providers.
paul@1075 236
paul@1089 237
        return t
paul@1075 238
paul@1075 239
    def _set_freebusy_providers(self, user, dt_string, t):
paul@1075 240
paul@1075 241
        "Set the given provider timestamp 'dt_string' and table 't'."
paul@1075 242
paul@1069 243
        pass
paul@1069 244
paul@1069 245
    def set_freebusy_providers(self, user, dt, providers):
paul@1069 246
paul@1069 247
        """
paul@1069 248
        Define the uncancelled events providing free/busy details beyond the
paul@1069 249
        given datetime 'dt'.
paul@1069 250
        """
paul@1069 251
paul@1075 252
        t = []
paul@1075 253
paul@1075 254
        for obj in providers:
paul@1075 255
            t.append((obj.get_uid(), obj.get_recurrenceid()))
paul@1075 256
paul@1075 257
        return self._set_freebusy_providers(user, format_datetime(dt), t)
paul@1069 258
paul@1069 259
    def append_freebusy_provider(self, user, provider):
paul@1069 260
paul@1069 261
        "For the given 'user', append the free/busy 'provider'."
paul@1069 262
paul@1075 263
        t = self._get_freebusy_providers(user)
paul@1075 264
        if not t:
paul@1075 265
            return False
paul@1075 266
paul@1075 267
        dt_string, t = t
paul@1075 268
        t.append((provider.get_uid(), provider.get_recurrenceid()))
paul@1075 269
paul@1075 270
        return self._set_freebusy_providers(user, dt_string, t)
paul@1069 271
paul@1069 272
    def remove_freebusy_provider(self, user, provider):
paul@1069 273
paul@1069 274
        "For the given 'user', remove the free/busy 'provider'."
paul@1069 275
paul@1075 276
        t = self._get_freebusy_providers(user)
paul@1075 277
        if not t:
paul@1075 278
            return False
paul@1075 279
paul@1075 280
        dt_string, t = t
paul@1075 281
        try:
paul@1075 282
            t.remove((provider.get_uid(), provider.get_recurrenceid()))
paul@1075 283
        except ValueError:
paul@1075 284
            return False
paul@1075 285
paul@1075 286
        return self._set_freebusy_providers(user, dt_string, t)
paul@1069 287
paul@1069 288
    # Free/busy period access.
paul@1069 289
paul@1077 290
    def get_freebusy(self, user, name=None, mutable=False):
paul@1069 291
paul@1069 292
        "Get free/busy details for the given 'user'."
paul@1069 293
paul@1069 294
        pass
paul@1069 295
paul@1077 296
    def get_freebusy_for_other(self, user, other, mutable=False):
paul@1069 297
paul@1069 298
        "For the given 'user', get free/busy details for the 'other' user."
paul@1069 299
paul@1069 300
        pass
paul@1069 301
paul@1071 302
    def get_freebusy_for_update(self, user, name=None):
paul@1071 303
paul@1071 304
        "Get free/busy details for the given 'user'."
paul@1071 305
paul@1077 306
        return self.get_freebusy(user, name, True)
paul@1071 307
paul@1071 308
    def get_freebusy_for_other_for_update(self, user, other):
paul@1071 309
paul@1071 310
        "For the given 'user', get free/busy details for the 'other' user."
paul@1071 311
paul@1077 312
        return self.get_freebusy_for_other(user, other, True)
paul@1071 313
paul@1069 314
    def set_freebusy(self, user, freebusy, name=None):
paul@1069 315
paul@1069 316
        "For the given 'user', set 'freebusy' details."
paul@1069 317
paul@1069 318
        pass
paul@1069 319
paul@1069 320
    def set_freebusy_for_other(self, user, freebusy, other):
paul@1069 321
paul@1069 322
        "For the given 'user', set 'freebusy' details for the 'other' user."
paul@1069 323
paul@1069 324
        pass
paul@1069 325
paul@1069 326
    # Tentative free/busy periods related to countering.
paul@1069 327
paul@1077 328
    def get_freebusy_offers(self, user, mutable=False):
paul@1069 329
paul@1069 330
        "Get free/busy offers for the given 'user'."
paul@1069 331
paul@1069 332
        pass
paul@1069 333
paul@1071 334
    def get_freebusy_offers_for_update(self, user):
paul@1071 335
paul@1071 336
        "Get free/busy offers for the given 'user'."
paul@1071 337
paul@1077 338
        return self.get_freebusy_offers(user, True)
paul@1071 339
paul@1069 340
    def set_freebusy_offers(self, user, freebusy):
paul@1069 341
paul@1069 342
        "For the given 'user', set 'freebusy' offers."
paul@1069 343
paul@1069 344
        return self.set_freebusy(user, freebusy, "freebusy-offers")
paul@1069 345
paul@1069 346
    # Requests and counter-proposals.
paul@1069 347
paul@1069 348
    def get_requests(self, user):
paul@1069 349
paul@1069 350
        "Get requests for the given 'user'."
paul@1069 351
paul@1069 352
        pass
paul@1069 353
paul@1069 354
    def set_requests(self, user, requests):
paul@1069 355
paul@1069 356
        "For the given 'user', set the list of queued 'requests'."
paul@1069 357
paul@1069 358
        pass
paul@1069 359
paul@1069 360
    def set_request(self, user, uid, recurrenceid=None, type=None):
paul@1069 361
paul@1069 362
        """
paul@1069 363
        For the given 'user', set the queued 'uid' and 'recurrenceid',
paul@1069 364
        indicating a request, along with any given 'type'.
paul@1069 365
        """
paul@1069 366
paul@1069 367
        pass
paul@1069 368
paul@1069 369
    def queue_request(self, user, uid, recurrenceid=None, type=None):
paul@1069 370
paul@1069 371
        """
paul@1069 372
        Queue a request for 'user' having the given 'uid'. If the optional
paul@1069 373
        'recurrenceid' is specified, the entry refers to a specific instance
paul@1069 374
        or occurrence of an event. The 'type' parameter can be used to indicate
paul@1069 375
        a specific type of request.
paul@1069 376
        """
paul@1069 377
paul@1069 378
        requests = self.get_requests(user) or []
paul@1069 379
paul@1069 380
        if not self.have_request(requests, uid, recurrenceid):
paul@1069 381
            return self.set_request(user, uid, recurrenceid, type)
paul@1069 382
paul@1069 383
        return False
paul@1069 384
paul@1069 385
    def dequeue_request(self, user, uid, recurrenceid=None):
paul@1069 386
paul@1069 387
        """
paul@1069 388
        Dequeue all requests for 'user' having the given 'uid'. If the optional
paul@1069 389
        'recurrenceid' is specified, all requests for that specific instance or
paul@1069 390
        occurrence of an event are dequeued.
paul@1069 391
        """
paul@1069 392
paul@1069 393
        requests = self.get_requests(user) or []
paul@1069 394
        result = []
paul@1069 395
paul@1069 396
        for request in requests:
paul@1069 397
            if request[:2] != (uid, recurrenceid):
paul@1069 398
                result.append(request)
paul@1069 399
paul@1069 400
        self.set_requests(user, result)
paul@1069 401
        return True
paul@1069 402
paul@1069 403
    def has_request(self, user, uid, recurrenceid=None, type=None, strict=False):
paul@1069 404
        return self.have_request(self.get_requests(user) or [], uid, recurrenceid, type, strict)
paul@1069 405
paul@1069 406
    def have_request(self, requests, uid, recurrenceid=None, type=None, strict=False):
paul@1069 407
paul@1069 408
        """
paul@1069 409
        Return whether 'requests' contains a request with the given 'uid' and
paul@1069 410
        any specified 'recurrenceid' and 'type'. If 'strict' is set to a true
paul@1069 411
        value, the precise type of the request must match; otherwise, any type
paul@1069 412
        of request for the identified object may be matched.
paul@1069 413
        """
paul@1069 414
paul@1069 415
        for request in requests:
paul@1069 416
            if request[:2] == (uid, recurrenceid) and (
paul@1069 417
                not strict or
paul@1069 418
                not request[2:] and not type or
paul@1069 419
                request[2:] and request[2] == type):
paul@1069 420
paul@1069 421
                return True
paul@1069 422
paul@1069 423
        return False
paul@1069 424
paul@1069 425
    def get_counters(self, user, uid, recurrenceid=None):
paul@1069 426
paul@1069 427
        """
paul@1069 428
        For the given 'user', return a list of users from whom counter-proposals
paul@1069 429
        have been received for the given 'uid' and optional 'recurrenceid'.
paul@1069 430
        """
paul@1069 431
paul@1069 432
        pass
paul@1069 433
paul@1069 434
    def get_counter(self, user, other, uid, recurrenceid=None):
paul@1069 435
paul@1069 436
        """
paul@1069 437
        For the given 'user', return the counter-proposal from 'other' for the
paul@1069 438
        given 'uid' and optional 'recurrenceid'.
paul@1069 439
        """
paul@1069 440
paul@1069 441
        pass
paul@1069 442
paul@1069 443
    def set_counter(self, user, other, node, uid, recurrenceid=None):
paul@1069 444
paul@1069 445
        """
paul@1069 446
        For the given 'user', store a counter-proposal received from 'other' the
paul@1069 447
        given 'node' representing that proposal for the given 'uid' and
paul@1069 448
        'recurrenceid'.
paul@1069 449
        """
paul@1069 450
paul@1069 451
        pass
paul@1069 452
paul@1069 453
    def remove_counters(self, user, uid, recurrenceid=None):
paul@1069 454
paul@1069 455
        """
paul@1069 456
        For the given 'user', remove all counter-proposals associated with the
paul@1069 457
        given 'uid' and 'recurrenceid'.
paul@1069 458
        """
paul@1069 459
paul@1069 460
        pass
paul@1069 461
paul@1069 462
    def remove_counter(self, user, other, uid, recurrenceid=None):
paul@1069 463
paul@1069 464
        """
paul@1069 465
        For the given 'user', remove any counter-proposal from 'other'
paul@1069 466
        associated with the given 'uid' and 'recurrenceid'.
paul@1069 467
        """
paul@1069 468
paul@1069 469
        pass
paul@1069 470
paul@1069 471
    # Event cancellation.
paul@1069 472
paul@1069 473
    def cancel_event(self, user, uid, recurrenceid=None):
paul@1069 474
paul@1069 475
        """
paul@1069 476
        Cancel an event for 'user' having the given 'uid'. If the optional
paul@1069 477
        'recurrenceid' is specified, a specific instance or occurrence of an
paul@1069 478
        event is cancelled.
paul@1069 479
        """
paul@1069 480
paul@1069 481
        pass
paul@1069 482
paul@1069 483
    def uncancel_event(self, user, uid, recurrenceid=None):
paul@1069 484
paul@1069 485
        """
paul@1069 486
        Uncancel an event for 'user' having the given 'uid'. If the optional
paul@1069 487
        'recurrenceid' is specified, a specific instance or occurrence of an
paul@1069 488
        event is uncancelled.
paul@1069 489
        """
paul@1069 490
paul@1069 491
        pass
paul@1069 492
paul@1069 493
    def remove_cancellations(self, user, uid, recurrenceid=None):
paul@1069 494
paul@1069 495
        """
paul@1069 496
        Remove cancellations for 'user' for any event having the given 'uid'. If
paul@1069 497
        the optional 'recurrenceid' is specified, a specific instance or
paul@1069 498
        occurrence of an event is affected.
paul@1069 499
        """
paul@1069 500
paul@1069 501
        # Remove all recurrence cancellations if a general event is indicated.
paul@1069 502
paul@1069 503
        if not recurrenceid:
paul@1069 504
            for _recurrenceid in self.get_cancelled_recurrences(user, uid):
paul@1069 505
                self.remove_cancellation(user, uid, _recurrenceid)
paul@1069 506
paul@1069 507
        return self.remove_cancellation(user, uid, recurrenceid)
paul@1069 508
paul@1069 509
    def remove_cancellation(self, user, uid, recurrenceid=None):
paul@1069 510
paul@1069 511
        """
paul@1069 512
        Remove a cancellation for 'user' for the event having the given 'uid'.
paul@1069 513
        If the optional 'recurrenceid' is specified, a specific instance or
paul@1069 514
        occurrence of an event is affected.
paul@1069 515
        """
paul@1069 516
paul@1069 517
        pass
paul@1069 518
paul@1069 519
class PublisherBase:
paul@1069 520
paul@1069 521
    "The core operations of a data publisher."
paul@1069 522
paul@1069 523
    def set_freebusy(self, user, freebusy):
paul@1069 524
paul@1069 525
        "For the given 'user', set 'freebusy' details."
paul@1069 526
paul@1069 527
        pass
paul@1069 528
paul@1069 529
class JournalBase:
paul@1069 530
paul@1069 531
    "The core operations of a journal system supporting quotas."
paul@1069 532
paul@1069 533
    # Quota and user identity/group discovery.
paul@1069 534
paul@1069 535
    def get_quotas(self):
paul@1069 536
paul@1069 537
        "Return a list of quotas."
paul@1069 538
paul@1069 539
        pass
paul@1069 540
paul@1069 541
    def get_quota_users(self, quota):
paul@1069 542
paul@1069 543
        "Return a list of quota users."
paul@1069 544
paul@1069 545
        pass
paul@1069 546
paul@1069 547
    # Groups of users sharing quotas.
paul@1069 548
paul@1069 549
    def get_groups(self, quota):
paul@1069 550
paul@1069 551
        "Return the identity mappings for the given 'quota' as a dictionary."
paul@1069 552
paul@1069 553
        pass
paul@1069 554
paul@1069 555
    def get_limits(self, quota):
paul@1069 556
paul@1069 557
        """
paul@1069 558
        Return the limits for the 'quota' as a dictionary mapping identities or
paul@1069 559
        groups to durations.
paul@1069 560
        """
paul@1069 561
paul@1069 562
        pass
paul@1069 563
paul@1089 564
    def set_limit(self, quota, group, limit):
paul@1089 565
paul@1089 566
        """
paul@1089 567
        For the given 'quota', set for a user 'group' the given 'limit' on
paul@1089 568
        resource usage.
paul@1089 569
        """
paul@1089 570
paul@1089 571
        pass
paul@1089 572
paul@1069 573
    # Free/busy period access for users within quota groups.
paul@1069 574
paul@1077 575
    def get_freebusy(self, quota, user, mutable=False):
paul@1069 576
paul@1069 577
        "Get free/busy details for the given 'quota' and 'user'."
paul@1069 578
paul@1069 579
        pass
paul@1069 580
paul@1071 581
    def get_freebusy_for_update(self, quota, user):
paul@1071 582
paul@1071 583
        "Get free/busy details for the given 'quota' and 'user'."
paul@1071 584
paul@1077 585
        return self.get_freebusy(quota, user, True)
paul@1071 586
paul@1069 587
    def set_freebusy(self, quota, user, freebusy):
paul@1069 588
paul@1069 589
        "For the given 'quota' and 'user', set 'freebusy' details."
paul@1069 590
paul@1069 591
        pass
paul@1069 592
paul@1069 593
    # Journal entry methods.
paul@1069 594
paul@1077 595
    def get_entries(self, quota, group, mutable=False):
paul@1069 596
paul@1069 597
        """
paul@1069 598
        Return a list of journal entries for the given 'quota' for the indicated
paul@1069 599
        'group'.
paul@1069 600
        """
paul@1069 601
paul@1069 602
        pass
paul@1069 603
paul@1071 604
    def get_entries_for_update(self, quota, group):
paul@1071 605
paul@1071 606
        """
paul@1071 607
        Return a list of journal entries for the given 'quota' for the indicated
paul@1071 608
        'group'.
paul@1071 609
        """
paul@1071 610
paul@1077 611
        return self.get_entries(quota, group, True)
paul@1071 612
paul@1069 613
    def set_entries(self, quota, group, entries):
paul@1069 614
paul@1069 615
        """
paul@1069 616
        For the given 'quota' and indicated 'group', set the list of journal
paul@1069 617
        'entries'.
paul@1069 618
        """
paul@1069 619
paul@1069 620
        pass
paul@1069 621
paul@1069 622
# vim: tabstop=4 expandtab shiftwidth=4