1.1 --- a/docs/wiki/FilesystemUsage Tue Feb 09 14:17:52 2016 +0100
1.2 +++ b/docs/wiki/FilesystemUsage Tue Feb 09 15:01:40 2016 +0100
1.3 @@ -53,9 +53,10 @@
1.4 .. of a quota across a number of users
1.5 ==
1.6 `journal`
1.7 -|| A directory containing transaction files, one per user or user group,
1.8 -.. describing confirmed reservations and retracted (cancelled) reservations for
1.9 -.. that user or group
1.10 +|| A directory containing consolidated schedules, one per user or user group,
1.11 +.. describing reservations for resources sharing a quota made by the indicated
1.12 +.. user or group, structured similarly to the `freebusy` file found in each
1.13 +.. resource's own store
1.14 {{{
1.15 journal/GROUP
1.16 journal/USER
2.1 --- a/imip_store.py Tue Feb 09 14:17:52 2016 +0100
2.2 +++ b/imip_store.py Tue Feb 09 15:01:40 2016 +0100
2.3 @@ -1013,9 +1013,9 @@
2.4 filename = self.get_object_in_store(quota, "freebusy", user)
2.5 if not filename or not isfile(filename):
2.6 return []
2.7 - else:
2.8 - return map(lambda t: FreeBusyPeriod(*t),
2.9 - (get_table or self._get_table_atomic)(quota, filename, [(4, None)]))
2.10 +
2.11 + return map(lambda t: FreeBusyPeriod(*t),
2.12 + (get_table or self._get_table_atomic)(quota, filename, [(4, None)]))
2.13
2.14 def set_freebusy(self, quota, user, freebusy, set_table=None):
2.15
2.16 @@ -1042,7 +1042,8 @@
2.17 if not filename or not isfile(filename):
2.18 return []
2.19
2.20 - return self._get_table_atomic(quota, filename, [(1, None), (3, None)])
2.21 + return map(lambda t: FreeBusyPeriod(*t),
2.22 + self._get_table_atomic(quota, filename, [(4, None)]))
2.23
2.24 def set_entries(self, quota, group, entries):
2.25
2.26 @@ -1055,7 +1056,8 @@
2.27 if not filename:
2.28 return False
2.29
2.30 - self._set_table_atomic(quota, filename, entries, [(1, ""), (3, "")])
2.31 + self._set_table_atomic(quota, filename,
2.32 + map(lambda fb: fb.as_tuple(strings_only=True), entries))
2.33 return True
2.34
2.35 # vim: tabstop=4 expandtab shiftwidth=4
3.1 --- a/imiptools/handlers/scheduling/quota.py Tue Feb 09 14:17:52 2016 +0100
3.2 +++ b/imiptools/handlers/scheduling/quota.py Tue Feb 09 15:01:40 2016 +0100
3.3 @@ -19,8 +19,7 @@
3.4 this program. If not, see <http://www.gnu.org/licenses/>.
3.5 """
3.6
3.7 -from imiptools.dates import format_datetime, format_duration, get_datetime, \
3.8 - get_duration, to_utc_datetime
3.9 +from imiptools.dates import get_duration, to_utc_datetime
3.10 from imiptools.data import get_uri
3.11 from imiptools.period import Endless
3.12 from datetime import timedelta
3.13 @@ -80,13 +79,12 @@
3.14 if total == Endless() or not expiry:
3.15 return
3.16
3.17 - # Obtain the journal entries and limits.
3.18 + # Update the journal entries.
3.19
3.20 journal = handler.get_journal()
3.21 entries = journal.get_entries(quota, group)
3.22 -
3.23 - if _add_to_entries(entries, handler.uid, handler.recurrenceid, format_duration(total), format_datetime(expiry)):
3.24 - journal.set_entries(quota, group, entries)
3.25 + handler.update_freebusy(entries, group, False)
3.26 + journal.set_entries(quota, group, entries)
3.27
3.28 def remove_from_quota(handler, args):
3.29
3.30 @@ -104,13 +102,12 @@
3.31 if total == Endless():
3.32 total = None
3.33
3.34 - # Obtain the journal entries and limits.
3.35 + # Update the journal entries.
3.36
3.37 journal = handler.get_journal()
3.38 entries = journal.get_entries(quota, group)
3.39 -
3.40 - if _remove_from_entries(entries, handler.uid, handler.recurrenceid, format_duration(total)):
3.41 - journal.set_entries(quota, group, entries)
3.42 + handler.remove_from_freebusy(entries)
3.43 + journal.set_entries(quota, group, entries)
3.44
3.45 def _get_quota_and_group(handler, args):
3.46
3.47 @@ -178,73 +175,10 @@
3.48 "Return the usage total according to the given 'entries'."
3.49
3.50 total = timedelta(0)
3.51 -
3.52 - for found_uid, found_recurrenceid, found_duration, found_expiry in entries:
3.53 - retraction = found_duration.startswith("-")
3.54 - multiplier = retraction and -1 or 1
3.55 - total += multiplier * get_duration(found_duration[retraction and 1 or 0:])
3.56 -
3.57 + for period in entries:
3.58 + total += period.get_duration()
3.59 return total
3.60
3.61 -def _add_to_entries(entries, uid, recurrenceid, duration, expiry):
3.62 -
3.63 - """
3.64 - Add to 'entries' an entry for the event having the given 'uid' and
3.65 - 'recurrenceid' with the given 'duration' and 'expiry' time.
3.66 - """
3.67 -
3.68 - confirmed = _find_applicable_entry(entries, uid, recurrenceid)
3.69 -
3.70 - # Where a previous entry still applies, retract it if different.
3.71 -
3.72 - if confirmed:
3.73 - found_uid, found_recurrenceid, found_duration, found_expiry = confirmed
3.74 - if found_duration != duration:
3.75 - entries.append((found_uid, found_recurrenceid, "-%s" % found_duration, found_expiry))
3.76 - else:
3.77 - return False
3.78 -
3.79 - # Without an applicable previous entry, add a new entry.
3.80 -
3.81 - entries.append((uid, recurrenceid, duration, expiry))
3.82 - return True
3.83 -
3.84 -def _remove_from_entries(entries, uid, recurrenceid, duration):
3.85 -
3.86 - """
3.87 - Remove from the given 'entries' any entry for the event having the given
3.88 - 'uid' and 'recurrenceid' with the given 'duration'.
3.89 - """
3.90 -
3.91 - confirmed = _find_applicable_entry(entries, uid, recurrenceid)
3.92 -
3.93 - # Where a previous entry still applies, retract it.
3.94 -
3.95 - if confirmed:
3.96 - found_uid, found_recurrenceid, found_duration, found_expiry = confirmed
3.97 - entries.append((found_uid, found_recurrenceid, "-%s" % found_duration, found_expiry))
3.98 - return True
3.99 -
3.100 - return False
3.101 -
3.102 -def _find_applicable_entry(entries, uid, recurrenceid):
3.103 -
3.104 - """
3.105 - Within 'entries', find any applicable previous entry for this event,
3.106 - using the 'uid' and 'recurrenceid'.
3.107 - """
3.108 -
3.109 - confirmed = None
3.110 -
3.111 - for found_uid, found_recurrenceid, found_duration, found_expiry in entries:
3.112 - if uid == found_uid and recurrenceid == found_recurrenceid:
3.113 - if found_duration.startswith("-"):
3.114 - confirmed = None
3.115 - else:
3.116 - confirmed = found_uid, found_recurrenceid, found_duration, found_expiry
3.117 -
3.118 - return confirmed
3.119 -
3.120 # Collective free/busy maintenance.
3.121
3.122 def schedule_across_quota(handler, args):
4.1 --- a/tests/test_resource_invitation_constraints_quota.sh Tue Feb 09 14:17:52 2016 +0100
4.2 +++ b/tests/test_resource_invitation_constraints_quota.sh Tue Feb 09 15:01:40 2016 +0100
4.3 @@ -167,7 +167,7 @@
4.4 # Check the quota (event is retracted).
4.5
4.6 [ -e "$JOURNALFILE" ] \
4.7 -&& [ `grep "event21@example.com" "$JOURNALFILE" | wc -l` = '2' ] \
4.8 +&& ! grep -q "event21@example.com" "$JOURNALFILE" \
4.9 && grep -q "event22@example.com" "$JOURNALFILE" \
4.10 && echo "Success" \
4.11 || echo "Failed"
4.12 @@ -206,8 +206,8 @@
4.13 # Check the quota (event is still confirmed).
4.14
4.15 [ -e "$JOURNALFILE" ] \
4.16 -&& [ `grep "event21@example.com" "$JOURNALFILE" | wc -l` = '2' ] \
4.17 -&& [ `grep "event22@example.com" "$JOURNALFILE" | wc -l` = '1' ] \
4.18 +&& ! grep -q "event21@example.com" "$JOURNALFILE" \
4.19 +&& grep -q "event22@example.com" "$JOURNALFILE" \
4.20 && echo "Success" \
4.21 || echo "Failed"
4.22
4.23 @@ -238,8 +238,8 @@
4.24 # Check the quota (event is still retracted and not newly confirmed).
4.25
4.26 [ -e "$JOURNALFILE" ] \
4.27 -&& [ `grep "event21@example.com" "$JOURNALFILE" | wc -l` = '2' ] \
4.28 -&& [ `grep "event22@example.com" "$JOURNALFILE" | wc -l` = '1' ] \
4.29 +&& ! grep -q "event21@example.com" "$JOURNALFILE" \
4.30 +&& grep -q "event22@example.com" "$JOURNALFILE" \
4.31 && echo "Success" \
4.32 || echo "Failed"
4.33
4.34 @@ -271,8 +271,8 @@
4.35 # Check the quota (event is newly confirmed).
4.36
4.37 [ -e "$JOURNALFILE" ] \
4.38 -&& [ `grep "event21@example.com" "$JOURNALFILE" | wc -l` = '3' ] \
4.39 -&& [ `grep "event22@example.com" "$JOURNALFILE" | wc -l` = '1' ] \
4.40 +&& grep -q "event21@example.com" "$JOURNALFILE" \
4.41 +&& grep -q "event22@example.com" "$JOURNALFILE" \
4.42 && echo "Success" \
4.43 || echo "Failed"
4.44
5.1 --- a/tests/test_resource_invitation_constraints_quota_recurring_limits.sh Tue Feb 09 14:17:52 2016 +0100
5.2 +++ b/tests/test_resource_invitation_constraints_quota_recurring_limits.sh Tue Feb 09 15:01:40 2016 +0100
5.3 @@ -172,7 +172,7 @@
5.4 # Check the quota (event is retracted).
5.5
5.6 ! [ -e "$JOURNALFILE1" ] \
5.7 -|| [ `grep "event25@example.com" "$JOURNALFILE1" | wc -l` = '2' ] \
5.8 +|| ! grep -q "event25@example.com" "$JOURNALFILE1" \
5.9 && echo "Success" \
5.10 || echo "Failed"
5.11
5.12 @@ -223,6 +223,6 @@
5.13 # Check the quota (event is confirmed for both resources).
5.14
5.15 [ -e "$JOURNALFILE2" ] \
5.16 -&& [ `grep "event25@example.com" "$JOURNALFILE2" | wc -l` = '1' ] \
5.17 +&& grep -q "event25@example.com" "$JOURNALFILE2" \
5.18 && echo "Success" \
5.19 || echo "Failed"
6.1 --- a/tools/update_quotas.py Tue Feb 09 14:17:52 2016 +0100
6.2 +++ b/tools/update_quotas.py Tue Feb 09 15:01:40 2016 +0100
6.3 @@ -41,14 +41,13 @@
6.4 "Remove from 'entries' events that end at or before 'expiry'."
6.5
6.6 removed = []
6.7 + i = 0
6.8
6.9 - i = 0
6.10 while i < len(entries):
6.11 - uid, recurrenceid, duration, found_expiry = entry = entries[i]
6.12 - found_expiry = get_datetime(found_expiry)
6.13 + period = entries[i]
6.14
6.15 - if found_expiry <= expiry:
6.16 - removed.append(entry)
6.17 + if period.get_end_point() <= expiry:
6.18 + removed.append(period)
6.19 del entries[i]
6.20 else:
6.21 i += 1
6.22 @@ -87,8 +86,8 @@
6.23 removed = remove_expired_entries(entries, expiry)
6.24
6.25 if verbose:
6.26 - for entry in removed:
6.27 - print >>stderr, "Removed", entry
6.28 + for period in removed:
6.29 + print >>stderr, "\t".join(("Removed",) + period.as_tuple(strings_only=True))
6.30
6.31 # Store the processed entries.
6.32
6.33 @@ -98,8 +97,8 @@
6.34 # Alternatively, just write the entries to standard output.
6.35
6.36 else:
6.37 - for entry in entries:
6.38 - print >>stdout, "\t".join([(s or "") for s in entry])
6.39 + for period in entries:
6.40 + print >>stdout, "\t".join(period.as_tuple(strings_only=True))
6.41 finally:
6.42 journal.release_lock(quota)
6.43