[CalendarServer-changes] [10867] CalendarServer/branches/users/gaya/sharedgroups
source_changes at macosforge.org
source_changes at macosforge.org
Thu Mar 7 14:42:21 PST 2013
Revision: 10867
http://trac.calendarserver.org//changeset/10867
Author: gaya at apple.com
Date: 2013-03-07 14:42:21 -0800 (Thu, 07 Mar 2013)
Log Message:
-----------
merge from trunk
Modified Paths:
--------------
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-no-master/14.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CalDAV/implicitattendeedelete.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CalDAV/implicitrecur2.xml
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/platform/darwin/od/dsquery.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/platform/darwin/od/setup_directory.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/platform/darwin/od/setup_testusers.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/platform/darwin/od/test/test_opendirectory.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/push/amppush.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/push/applepush.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/push/test/test_amppush.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/push/test/test_applepush.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/push/test/test_notifier.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tap/caldav.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tap/util.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/ampnotifications.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/anonymize.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/backup_pg.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/bootstrapdatabase.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/calverify.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/calverify_diff.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/changeip_calendar.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/cmdline.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/config.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/dbinspect.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/dkimtool.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/doublequotefix.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/export.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/fixcalendardata.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/gateway.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/icalsplit.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/loadaugmentdb.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/managepostgres.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/managetimezones.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/migrate.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/migrate_verify.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/notifications.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/obliterate.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/principals.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/purge.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/push.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/resources.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/shell/terminal.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/test/test_calverify.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/test/test_gateway.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/upgrade.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/util.py
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/validcalendardata.py
CalendarServer/branches/users/gaya/sharedgroups/conf/caldavd-apple.plist
CalendarServer/branches/users/gaya/sharedgroups/conf/caldavd-test.plist
CalendarServer/branches/users/gaya/sharedgroups/contrib/migration/calendarcommonextra.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/migration/calendardemotion.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/migration/calendarmigrator.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/migration/calendarpromotion.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/migration/test/test_migrator.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/benchlib.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/benchmark.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/compare.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/display-calendar-events.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/httpauth.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/loadtest/ampsim.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/loadtest/ical.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/loadtest/population.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/loadtest/sim.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/massupload.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/report.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/sqlusage/sqlusage.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/sqlwatch.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/stats.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/upload.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/anonymous_log.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/dtraceanalyze.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/fakecalendardata.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/harpoon.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/monitoranalysis.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/monitorsplit.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/netstatus.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/pg_stats_analysis.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/protocolanalysis.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/readStats.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/request_monitor.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/sortrecurrences.py
CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/sqldata_from_path.py
CalendarServer/branches/users/gaya/sharedgroups/setup.py
CalendarServer/branches/users/gaya/sharedgroups/support/version.py
CalendarServer/branches/users/gaya/sharedgroups/test
CalendarServer/branches/users/gaya/sharedgroups/twext/enterprise/dal/parseschema.py
CalendarServer/branches/users/gaya/sharedgroups/twext/enterprise/dal/record.py
CalendarServer/branches/users/gaya/sharedgroups/twext/enterprise/dal/test/test_record.py
CalendarServer/branches/users/gaya/sharedgroups/twext/enterprise/queue.py
CalendarServer/branches/users/gaya/sharedgroups/twext/internet/gaiendpoint.py
CalendarServer/branches/users/gaya/sharedgroups/twext/python/_plistlib.py
CalendarServer/branches/users/gaya/sharedgroups/twext/python/log.py
CalendarServer/branches/users/gaya/sharedgroups/twext/python/memcacheclient.py
CalendarServer/branches/users/gaya/sharedgroups/twext/web2/dav/resource.py
CalendarServer/branches/users/gaya/sharedgroups/twext/web2/fileupload.py
CalendarServer/branches/users/gaya/sharedgroups/twext/web2/http_headers.py
CalendarServer/branches/users/gaya/sharedgroups/twext/web2/server.py
CalendarServer/branches/users/gaya/sharedgroups/twext/web2/test/test_client.py
CalendarServer/branches/users/gaya/sharedgroups/twext/who/__init__.py
CalendarServer/branches/users/gaya/sharedgroups/twext/who/directory.py
CalendarServer/branches/users/gaya/sharedgroups/twext/who/idirectory.py
CalendarServer/branches/users/gaya/sharedgroups/twext/who/index.py
CalendarServer/branches/users/gaya/sharedgroups/twext/who/test/test_directory.py
CalendarServer/branches/users/gaya/sharedgroups/twext/who/test/test_xml.py
CalendarServer/branches/users/gaya/sharedgroups/twext/who/util.py
CalendarServer/branches/users/gaya/sharedgroups/twext/who/xml.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/backup.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/datafilters/hiddeninstance.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/datafilters/test/test_hiddeninstances.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/directory/test/test_guidchange.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/directory/test/test_ldapdirectory.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/directory/test/test_livedirectory.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/directory/test/test_principal.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/extensions.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/ical.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/localization.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/method/put.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/query/expression.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/query/sqlgenerator.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/resource.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/icaldiff.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/imip/outbound.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/implicit.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/itip.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/processing.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/test/test_icaldiff.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/test/test_itip.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/test/test_utils.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/sharing.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/stdconfig.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/test/util.py
CalendarServer/branches/users/gaya/sharedgroups/txdav/base/datastore/file.py
CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/current-oracle-dialect.sql
CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/current.sql
CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/test/util.py
CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/upgrade/sql/test/test_upgrade.py
CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/upgrade/sql/upgrade.py
Added Paths:
-----------
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/1.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/10.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/11.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/12.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/13.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/14.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/15.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/16.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/17.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/2.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/3.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/4.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/5.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/6.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/7.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/8.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/9.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/1.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/10.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/11.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/12.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/2.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/3.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/4.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/5.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/6.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/7.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/8.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/9.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/1.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/2.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/3.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/4.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/1.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/2.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/3.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/4.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/1.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/2.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/3.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/4.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/1.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/2.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/3.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/4.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/5.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/6.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/7.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/8.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CalDAV/implicitauto10.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CalDAV/implicitautopast.xml
CalendarServer/branches/users/gaya/sharedgroups/twext/who/aggregate.py
CalendarServer/branches/users/gaya/sharedgroups/twext/who/expression.py
CalendarServer/branches/users/gaya/sharedgroups/twext/who/test/test_aggregate.py
CalendarServer/branches/users/gaya/sharedgroups/twext/who/test/test_expression.py
CalendarServer/branches/users/gaya/sharedgroups/twext/who/test/test_util.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/imip/test/test_inbound.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/imip/test/test_outbound.py
CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/old/oracle-dialect/v16.sql
CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/old/postgres-dialect/v16.sql
CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_16_to_17.sql
CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/upgrades/postgres-dialect/upgrade_from_16_to_17.sql
CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/upgrade/sql/others/test/
CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/upgrade/sql/others/test/__init__.py
CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/upgrade/sql/others/test/test_attachment_migration.py
Removed Paths:
-------------
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/1.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/10.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/11.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/12.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/13.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/14.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/15.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/16.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/17.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/2.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/3.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/4.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/5.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/6.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/7.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/8.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/9.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/1.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/10.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/11.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/12.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/2.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/3.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/4.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/5.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/6.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/7.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/8.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/9.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/1.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/2.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/3.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/4.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/1.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/2.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/3.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/4.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/1.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/2.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/3.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/4.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/1.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/2.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/3.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/4.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/5.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/6.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/7.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/8.ics
CalendarServer/branches/users/gaya/sharedgroups/bin/calendarserver_warmup
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/platform/darwin/_sacl.so
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/warmup.py
CalendarServer/branches/users/gaya/sharedgroups/doc/datafilters/
CalendarServer/branches/users/gaya/sharedgroups/support/directorysetup.py
CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/imip/resource.py
Property Changed:
----------------
CalDAVTester/branches/users/gaya/sharedgroupstester/
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/1.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/10.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/11.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/12.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/13.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/14.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/15.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/16.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/17.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/18.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/19.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/2.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/20.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/21.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/22.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/23.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/24.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/25.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/26.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/27.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/28.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/29.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/3.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/30.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/31.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/32.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/4.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/5.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/6.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/7.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/8.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/9.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/schedulechanges/organizerchange/1.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/schedulechanges/organizerchange/2.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/schedulechanges/organizerchange/3.xml
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/schedulechanges/organizerchange/4.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/schedulechanges/organizerchange/5.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/schedulechanges/organizerchange/6.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/schedulechanges/organizerchange/7.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/schedulechanges/organizerchange/8.ics
CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CalDAV/implicitoptions.xml
CalendarServer/branches/users/gaya/sharedgroups/
CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/
CalendarServer/branches/users/gaya/sharedgroups/conf/
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev:7584
/CalDAVTester/branches/release/CalDAVTester-4.3-dev:10193
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes:8221-8346
/CalDAVTester/branches/users/cdaboo/conditional-4466:4467-4469
/CalDAVTester/branches/users/cdaboo/implicitauto-2948:2949-2989
/CalDAVTester/branches/users/cdaboo/location-partial-accept-3574:3575-3581
/CalDAVTester/branches/users/cdaboo/managed-attachments:9986-10145
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228:5229-5440
/CalDAVTester/trunk:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev:7584
/CalDAVTester/branches/release/CalDAVTester-4.3-dev:10193
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes:8221-8346
/CalDAVTester/branches/users/cdaboo/conditional-4466:4467-4469
/CalDAVTester/branches/users/cdaboo/implicitauto-2948:2949-2989
/CalDAVTester/branches/users/cdaboo/location-partial-accept-3574:3575-3581
/CalDAVTester/branches/users/cdaboo/managed-attachments:9986-10145
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228:5229-5440
/CalDAVTester/trunk:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/1.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/1.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/1.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/1.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/1.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/1.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/1.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/1.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/1.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/1.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/1.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/1.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/1.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/1.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/1.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/1.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/1.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/1.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/1.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/1.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/1.xml:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/10.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/10.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/10.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/10.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/10.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/10.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/10.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/10.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/10.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/10.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/10.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/10.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/10.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/10.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/10.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/10.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/10.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/10.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/10.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/10.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/10.xml:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/11.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/11.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/11.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/11.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/11.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/11.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/11.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/11.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/11.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/11.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/11.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/11.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/11.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/11.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/11.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/11.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/11.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/11.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/11.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/11.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/11.xml:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/12.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/12.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/12.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/12.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/12.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/12.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/12.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/12.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/12.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/12.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/12.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/12.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/12.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/12.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/12.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/12.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/12.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/12.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/12.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/12.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/12.xml:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/13.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/13.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/13.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/13.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/13.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/13.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/13.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/13.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/13.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/13.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/13.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/13.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/13.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/13.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/13.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/13.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/13.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/13.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/13.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/13.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/13.xml:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/14.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/14.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/14.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/14.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/14.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/14.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/14.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/14.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/14.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/14.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/14.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/14.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/14.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/14.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/14.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/14.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/14.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/14.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/14.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/14.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/14.xml:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/15.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/15.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/15.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/15.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/15.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/15.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/15.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/15.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/15.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/15.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/15.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/15.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/15.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/15.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/15.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/15.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/15.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/15.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/15.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/15.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/15.xml:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/16.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/16.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/16.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/16.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/16.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/16.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/16.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/16.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/16.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/16.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/16.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/16.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/16.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/16.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/16.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/16.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/16.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/16.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/16.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/16.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/16.xml:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/17.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/17.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/17.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/17.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/17.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/17.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/17.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/17.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/17.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/17.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/17.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/17.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/17.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/17.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/17.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/17.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/17.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/17.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/17.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/17.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/17.xml:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/18.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/18.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/18.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/18.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/18.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/18.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/18.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/18.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/18.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/18.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/18.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/18.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/18.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/18.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/18.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/18.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/18.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/18.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/18.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/18.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/18.xml:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/19.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/19.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/19.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/19.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/19.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/19.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/19.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/19.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/19.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/19.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/19.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/19.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/19.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/19.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/19.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/19.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/19.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/19.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/19.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/19.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/19.xml:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/2.ics
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/2.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/2.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/2.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/2.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/2.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/2.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/2.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/2.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/2.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/2.ics:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/2.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/2.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/2.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/2.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/2.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/2.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/2.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/2.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/2.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/2.ics:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/20.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/20.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/20.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/20.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/20.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/20.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/20.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/20.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/20.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/20.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/20.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/20.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/20.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/20.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/20.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/20.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/20.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/20.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/20.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/20.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/20.xml:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/21.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/21.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/21.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/21.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/21.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/21.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/21.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/21.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/21.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/21.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/21.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/21.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/21.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/21.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/21.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/21.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/21.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/21.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/21.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/21.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/21.xml:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/22.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/22.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/22.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/22.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/22.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/22.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/22.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/22.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/22.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/22.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/22.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/22.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/22.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/22.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/22.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/22.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/22.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/22.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/22.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/22.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/22.xml:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/23.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/23.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/23.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/23.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/23.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/23.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/23.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/23.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/23.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/23.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/23.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/23.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/23.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/23.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/23.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/23.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/23.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/23.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/23.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/23.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/23.xml:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/24.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/24.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/24.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/24.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/24.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/24.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/24.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/24.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/24.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/24.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/24.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/24.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/24.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/24.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/24.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/24.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/24.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/24.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/24.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/24.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/24.xml:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/25.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/25.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/25.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/25.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/25.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/25.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/25.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/25.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/25.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/25.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/25.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/25.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/25.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/25.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/25.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/25.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/25.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/25.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/25.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/25.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/25.xml:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/26.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/26.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/26.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/26.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/26.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/26.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/26.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/26.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/26.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/26.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/26.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/26.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/26.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/26.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/26.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/26.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/26.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/26.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/26.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/26.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/26.xml:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/27.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/27.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/27.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/27.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/27.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/27.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/27.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/27.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/27.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/27.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/27.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/27.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/27.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/27.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/27.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/27.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/27.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/27.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/27.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/27.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/27.xml:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/28.ics
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/28.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/28.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/28.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/28.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/28.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/28.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/28.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/28.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/28.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/28.ics:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/28.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/28.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/28.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/28.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/28.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/28.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/28.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/28.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/28.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/28.ics:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/29.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/29.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/29.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/29.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/29.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/29.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/29.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/29.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/29.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/29.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/29.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/29.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/29.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/29.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/29.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/29.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/29.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/29.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/29.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/29.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/29.xml:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/3.ics
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/3.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/3.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/3.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/3.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/3.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/3.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/3.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/3.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/3.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/3.ics:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/3.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/3.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/3.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/3.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/3.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/3.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/3.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/3.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/3.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/3.ics:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/30.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/30.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/30.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/30.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/30.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/30.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/30.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/30.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/30.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/30.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/30.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/30.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/30.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/30.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/30.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/30.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/30.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/30.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/30.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/30.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/30.xml:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/31.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/31.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/31.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/31.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/31.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/31.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/31.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/31.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/31.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/31.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/31.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/31.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/31.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/31.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/31.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/31.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/31.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/31.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/31.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/31.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/31.xml:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/32.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/32.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/32.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/32.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/32.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/32.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/32.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/32.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/32.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/32.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/32.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/32.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/32.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/32.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/32.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/32.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/32.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/32.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/32.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/32.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/32.xml:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/4.ics
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/4.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/4.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/4.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/4.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/4.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/4.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/4.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/4.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/4.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/4.ics:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/4.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/4.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/4.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/4.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/4.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/4.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/4.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/4.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/4.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/4.ics:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/5.ics
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/5.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/5.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/5.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/5.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/5.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/5.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/5.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/5.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/5.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/5.ics:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/5.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/5.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/5.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/5.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/5.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/5.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/5.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/5.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/5.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/5.ics:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/6.ics
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/6.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/6.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/6.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/6.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/6.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/6.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/6.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/6.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/6.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/6.ics:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/6.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/6.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/6.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/6.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/6.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/6.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/6.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/6.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/6.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/6.ics:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/7.ics
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/7.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/7.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/7.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/7.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/7.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/7.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/7.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/7.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/7.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/7.ics:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/7.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/7.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/7.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/7.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/7.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/7.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/7.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/7.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/7.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/7.ics:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/8.ics
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/8.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/8.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/8.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/8.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/8.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/8.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/8.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/8.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/8.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/8.ics:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/8.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/8.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/8.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/8.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/8.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/8.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/8.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/8.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/8.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/8.ics:10010-10865
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/errors/9.ics
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/9.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/9.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/9.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/9.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/9.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/9.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/9.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/9.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/9.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/9.ics:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/errors/9.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/errors/9.txt:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/errors/9.txt:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/errors/9.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/errors/9.txt:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/errors/9.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/errors/9.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/errors/9.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/errors/9.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/errors/9.ics:10010-10865
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/1.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/1.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/1.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,61 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
-DURATION:PT1H
-SUMMARY:event 1
-UID:event1 at ninevah.local
-ORGANIZER;CN=$username1::$cuaddr1:
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddr1:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:$cuaddr3:
-RRULE:FREQ=DAILY
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0102T100000
-DURATION:PT1H
-SUMMARY:event 1
-UID:event1 at ninevah.local
-ORGANIZER;CN=$username1::$cuaddr1:
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddr1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:$cuaddr2:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:$cuaddr3:
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
-DURATION:PT1H
-SUMMARY:event 1
-UID:event1 at ninevah.local
-ORGANIZER;CN=$username1::$cuaddr1:
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddr1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:$cuaddr2:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:$cuaddr3:
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/1.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/1.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/1.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/1.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,61 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
+DURATION:PT1H
+SUMMARY:event 1
+UID:event1 at ninevah.local
+ORGANIZER;CN=$username1::$cuaddr1:
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddr1:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:$cuaddr3:
+RRULE:FREQ=DAILY
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0102T100000
+DURATION:PT1H
+SUMMARY:event 1
+UID:event1 at ninevah.local
+ORGANIZER;CN=$username1::$cuaddr1:
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddr1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:$cuaddr2:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:$cuaddr3:
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
+DURATION:PT1H
+SUMMARY:event 1
+UID:event1 at ninevah.local
+ORGANIZER;CN=$username1::$cuaddr1:
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddr1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:$cuaddr2:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:$cuaddr3:
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/10.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/10.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/10.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,64 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-RRULE:FREQ=DAILY
-SEQUENCE:1
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0102T100000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=DECLINED;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-SEQUENCE:1
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-SEQUENCE:1
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/10.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/10.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/10.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/10.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,64 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+RRULE:FREQ=DAILY
+SEQUENCE:1
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0102T100000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=DECLINED;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+SEQUENCE:1
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+SEQUENCE:1
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/11.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/11.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/11.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,37 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
-SEQUENCE:1
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/11.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/11.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/11.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/11.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,37 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
+SEQUENCE:1
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/12.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/12.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/12.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,64 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-RRULE:FREQ=DAILY
-SEQUENCE:2
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0102T120000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-SEQUENCE:2
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-SEQUENCE:2
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/12.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/12.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/12.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/12.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,64 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+RRULE:FREQ=DAILY
+SEQUENCE:2
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0102T120000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+SEQUENCE:2
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+SEQUENCE:2
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/13.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/13.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/13.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,65 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
-RRULE:FREQ=DAILY
-SEQUENCE:2
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0102T120000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
-SEQUENCE:2
-TRANSP:TRANSPARENT
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
-SEQUENCE:2
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/13.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/13.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/13.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/13.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,65 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
+RRULE:FREQ=DAILY
+SEQUENCE:2
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0102T120000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
+SEQUENCE:2
+TRANSP:TRANSPARENT
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
+SEQUENCE:2
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/14.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/14.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/14.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,52 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0102T120000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
-SEQUENCE:2
-TRANSP:TRANSPARENT
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
-SEQUENCE:2
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/14.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/14.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/14.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/14.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,52 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0102T120000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
+SEQUENCE:2
+TRANSP:TRANSPARENT
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
+SEQUENCE:2
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/15.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/15.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/15.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,64 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=1.2;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-RRULE:FREQ=DAILY
-SEQUENCE:2
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0102T120000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=DECLINED;SCHEDULE-STATUS=2.0;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-SEQUENCE:2
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=DECLINED;SCHEDULE-STATUS=2.0;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=1.2;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-SEQUENCE:2
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/15.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/15.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/15.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/15.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,64 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=1.2;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+RRULE:FREQ=DAILY
+SEQUENCE:2
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0102T120000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=DECLINED;SCHEDULE-STATUS=2.0;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+SEQUENCE:2
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=DECLINED;SCHEDULE-STATUS=2.0;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=1.2;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+SEQUENCE:2
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/16.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/16.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/16.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,64 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-RRULE:FREQ=DAILY
-SEQUENCE:2
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0102T140000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-SEQUENCE:3
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
-DURATION:PT1H
-SUMMARY:event 1-2
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=DECLINED;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-SEQUENCE:2
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/16.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/16.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/16.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/16.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,64 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+RRULE:FREQ=DAILY
+SEQUENCE:2
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0102T140000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+SEQUENCE:3
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
+DURATION:PT1H
+SUMMARY:event 1-2
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=DECLINED;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+SEQUENCE:2
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/17.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/17.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/17.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,38 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0102T140000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-SEQUENCE:3
-TRANSP:TRANSPARENT
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/17.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/17.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/17.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/17.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,38 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0102T140000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+SEQUENCE:3
+TRANSP:TRANSPARENT
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/2.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/2.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/2.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,61 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
-DURATION:PT1H
-SUMMARY:event 1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-RRULE:FREQ=DAILY
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0102T100000
-DURATION:PT1H
-SUMMARY:event 1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
-DURATION:PT1H
-SUMMARY:event 1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/2.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/2.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/2.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/2.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,61 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
+DURATION:PT1H
+SUMMARY:event 1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+RRULE:FREQ=DAILY
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0102T100000
+DURATION:PT1H
+SUMMARY:event 1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
+DURATION:PT1H
+SUMMARY:event 1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/3.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/3.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/3.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,37 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
-DURATION:PT1H
-SUMMARY:event 1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddr1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-TRANSP:TRANSPARENT
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/3.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/3.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/3.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/3.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,37 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
+DURATION:PT1H
+SUMMARY:event 1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddr1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+TRANSP:TRANSPARENT
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/4.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/4.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/4.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,61 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
-DURATION:PT1H
-SUMMARY:event 1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-RRULE:FREQ=DAILY
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0102T100000
-DURATION:PT1H
-SUMMARY:event 1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=DECLINED;SCHEDULE-STATUS=2.0;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
-DURATION:PT1H
-SUMMARY:event 1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/4.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/4.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/4.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/4.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,61 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
+DURATION:PT1H
+SUMMARY:event 1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+RRULE:FREQ=DAILY
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0102T100000
+DURATION:PT1H
+SUMMARY:event 1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=DECLINED;SCHEDULE-STATUS=2.0;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
+DURATION:PT1H
+SUMMARY:event 1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/5.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/5.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/5.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,36 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
-DURATION:PT1H
-SUMMARY:event 1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddr1:
-ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/5.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/5.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/5.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/5.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,36 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
+DURATION:PT1H
+SUMMARY:event 1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddr1:
+ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/6.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/6.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/6.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,61 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-RRULE:FREQ=DAILY
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0102T100000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=DECLINED;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/6.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/6.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/6.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/6.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,61 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+RRULE:FREQ=DAILY
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0102T100000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=DECLINED;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/7.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/7.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/7.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,67 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-RRULE:FREQ=DAILY
-SEQUENCE:1
-TRANSP:TRANSPARENT
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0102T100000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=DECLINED;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-SEQUENCE:1
-TRANSP:TRANSPARENT
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-SEQUENCE:1
-TRANSP:TRANSPARENT
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/7.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/7.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/7.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/7.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,67 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+RRULE:FREQ=DAILY
+SEQUENCE:1
+TRANSP:TRANSPARENT
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0102T100000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=DECLINED;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+SEQUENCE:1
+TRANSP:TRANSPARENT
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+SEQUENCE:1
+TRANSP:TRANSPARENT
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/8.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/8.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/8.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,37 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
-SEQUENCE:1
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/8.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/8.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/8.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/8.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,37 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
+SEQUENCE:1
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/9.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/9.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/9.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,64 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-RRULE:FREQ=DAILY
-SEQUENCE:1
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0102T100000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=DECLINED;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-SEQUENCE:1
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
-DURATION:PT1H
-SUMMARY:event 1-1
-UID:event1 at ninevah.local
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-SEQUENCE:1
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/9.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/9.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/9.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/9.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,64 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+RRULE:FREQ=DAILY
+SEQUENCE:1
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0102T100000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=DECLINED;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+SEQUENCE:1
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0103T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0103T100000
+DURATION:PT1H
+SUMMARY:event 1-1
+UID:event1 at ninevah.local
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$username3:;PARTSTAT=ACCEPTED;EMAIL=$email3::$cuaddrurn3:
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+SEQUENCE:1
+END:VEVENT
+END:VCALENDAR
Modified: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-no-master/14.ics
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-no-master/14.ics 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/attendeedelete/recurring-no-master/14.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -31,7 +31,7 @@
ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email2::$cuaddrurn2:
ATTENDEE;CN=$username3:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email3::$cuaddrurn3:
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
SEQUENCE:2
TRANSP:TRANSPARENT
END:VEVENT
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/1.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/1.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/1.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,18 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Example Inc.//Example Calendar//EN
-BEGIN:VEVENT
-UID:event-1
-DTSTART:$now.8:T200000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddralt1:
-ATTENDEE;CN=$resourcename8::$rcuaddralt8:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1::$cuaddralt1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:OPAQUE
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/1.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/1.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/1.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/1.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,18 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Example Inc.//Example Calendar//EN
+BEGIN:VEVENT
+UID:event-1
+DTSTART:$now.8:T200000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddralt1:
+ATTENDEE;CN=$resourcename8::$rcuaddralt8:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1::$cuaddralt1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/10.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/10.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/10.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,19 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
-BEGIN:VEVENT
-UID:event-2
-DTSTART:$now.8:T203000Z
-DURATION:PT30M
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename8:;PARTSTAT=ACCEPTED:$rcuaddrurn8:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:OPAQUE
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/10.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/10.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/10.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/10.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,19 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:event-2
+DTSTART:$now.8:T203000Z
+DURATION:PT30M
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename8:;PARTSTAT=ACCEPTED:$rcuaddrurn8:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/11.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/11.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/11.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,18 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Example Inc.//Example Calendar//EN
-BEGIN:VEVENT
-UID:event-1
-DTSTART:$now.8:T200000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$resourcename8:;RSVP=TRUE;SCHEDULE-STATUS=1.2:$rcuaddrurn8:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:OPAQUE
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/11.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/11.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/11.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/11.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,18 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Example Inc.//Example Calendar//EN
+BEGIN:VEVENT
+UID:event-1
+DTSTART:$now.8:T200000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$resourcename8:;RSVP=TRUE;SCHEDULE-STATUS=1.2:$rcuaddrurn8:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/12.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/12.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/12.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,18 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
-BEGIN:VEVENT
-UID:event-1
-DTSTART:$now.8:T200000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$resourcename8:;RSVP=TRUE:$rcuaddrurn8:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:TRANSPARENT
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/12.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/12.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/12.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/12.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,18 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:event-1
+DTSTART:$now.8:T200000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$resourcename8:;RSVP=TRUE:$rcuaddrurn8:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:TRANSPARENT
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/2.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/2.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/2.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,18 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Example Inc.//Example Calendar//EN
-BEGIN:VEVENT
-UID:event-1
-DTSTART:$now.8:T200000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$resourcename8:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0:$rcuaddrurn8:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:OPAQUE
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/2.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/2.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/2.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/2.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,18 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Example Inc.//Example Calendar//EN
+BEGIN:VEVENT
+UID:event-1
+DTSTART:$now.8:T200000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$resourcename8:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0:$rcuaddrurn8:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/3.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/3.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/3.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,18 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
-BEGIN:VEVENT
-UID:event-1
-DTSTART:$now.8:T200000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$resourcename8:;PARTSTAT=ACCEPTED:$rcuaddrurn8:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:OPAQUE
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/3.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/3.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/3.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/3.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,18 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:event-1
+DTSTART:$now.8:T200000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$resourcename8:;PARTSTAT=ACCEPTED:$rcuaddrurn8:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/4.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/4.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/4.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,19 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Example Inc.//Example Calendar//EN
-BEGIN:VEVENT
-UID:event-2
-DTSTART:$now.8:T203000Z
-DURATION:PT30M
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddralt1:
-ATTENDEE;CN=$username2:;RSVP=TRUE:$cuaddralt2:
-ATTENDEE;CN=$resourcename8::$rcuaddralt8:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1::$cuaddralt1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:OPAQUE
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/4.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/4.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/4.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/4.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,19 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Example Inc.//Example Calendar//EN
+BEGIN:VEVENT
+UID:event-2
+DTSTART:$now.8:T203000Z
+DURATION:PT30M
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddralt1:
+ATTENDEE;CN=$username2:;RSVP=TRUE:$cuaddralt2:
+ATTENDEE;CN=$resourcename8::$rcuaddralt8:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1::$cuaddralt1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/5.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/5.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/5.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,19 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Example Inc.//Example Calendar//EN
-BEGIN:VEVENT
-UID:event-2
-DTSTART:$now.8:T203000Z
-DURATION:PT30M
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename8:;RSVP=TRUE;SCHEDULE-STATUS=1.2:$rcuaddrurn8:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:OPAQUE
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/5.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/5.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/5.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/5.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,19 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Example Inc.//Example Calendar//EN
+BEGIN:VEVENT
+UID:event-2
+DTSTART:$now.8:T203000Z
+DURATION:PT30M
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename8:;RSVP=TRUE;SCHEDULE-STATUS=1.2:$rcuaddrurn8:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/6.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/6.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/6.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,19 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
-BEGIN:VEVENT
-UID:event-2
-DTSTART:$now.8:T203000Z
-DURATION:PT30M
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename8:;RSVP=TRUE:$rcuaddrurn8:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:TRANSPARENT
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/6.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/6.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/6.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/6.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,19 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:event-2
+DTSTART:$now.8:T203000Z
+DURATION:PT30M
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename8:;RSVP=TRUE:$rcuaddrurn8:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:TRANSPARENT
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/7.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/7.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/7.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,19 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
-BEGIN:VEVENT
-UID:event-2
-DTSTART:$now.8:T203000Z
-DURATION:PT30M
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename8:;RSVP=TRUE:$rcuaddrurn8:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:TRANSPARENT
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/7.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/7.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/7.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/7.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,19 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:event-2
+DTSTART:$now.8:T203000Z
+DURATION:PT30M
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename8:;RSVP=TRUE:$rcuaddrurn8:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:TRANSPARENT
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/8.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/8.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/8.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,19 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
-BEGIN:VEVENT
-UID:event-2
-DTSTART:$now.8:T203000Z
-DURATION:PT30M
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename8:;PARTSTAT=DECLINED:$rcuaddrurn8:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:TRANSPARENT
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/8.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/8.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/8.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/8.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,19 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:event-2
+DTSTART:$now.8:T203000Z
+DURATION:PT30M
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename8:;PARTSTAT=DECLINED:$rcuaddrurn8:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:TRANSPARENT
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/9.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/9.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/9.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,19 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Example Inc.//Example Calendar//EN
-BEGIN:VEVENT
-UID:event-2
-DTSTART:$now.8:T203000Z
-DURATION:PT30M
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename8:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0:$rcuaddrurn8:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:OPAQUE
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/9.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/auto10/suite1/9.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/9.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/auto10/suite1/9.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,19 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Example Inc.//Example Calendar//EN
+BEGIN:VEVENT
+UID:event-2
+DTSTART:$now.8:T203000Z
+DURATION:PT30M
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename8:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0:$rcuaddrurn8:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/1.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite1/1.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/1.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,19 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Example Inc.//Example Calendar//EN
-BEGIN:VEVENT
-UID:event-1
-DTSTART:$now.-8:T200000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddralt1:
-ATTENDEE;CN=$username2:;RSVP=TRUE:$cuaddralt2:
-ATTENDEE;CN=$resourcename1::$rcuaddralt1:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1::$cuaddralt1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:OPAQUE
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/1.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite1/1.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/1.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/1.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,19 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Example Inc.//Example Calendar//EN
+BEGIN:VEVENT
+UID:event-1
+DTSTART:$now.-8:T200000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddralt1:
+ATTENDEE;CN=$username2:;RSVP=TRUE:$cuaddralt2:
+ATTENDEE;CN=$resourcename1::$rcuaddralt1:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1::$cuaddralt1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/2.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite1/2.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/2.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,19 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Example Inc.//Example Calendar//EN
-BEGIN:VEVENT
-UID:event-1
-DTSTART:$now.-8:T200000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename1:;RSVP=TRUE;SCHEDULE-STATUS=1.2:$rcuaddrurn1:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:OPAQUE
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/2.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite1/2.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/2.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/2.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,19 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Example Inc.//Example Calendar//EN
+BEGIN:VEVENT
+UID:event-1
+DTSTART:$now.-8:T200000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename1:;RSVP=TRUE;SCHEDULE-STATUS=1.2:$rcuaddrurn1:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/3.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite1/3.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/3.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,19 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
-BEGIN:VEVENT
-UID:event-1
-DTSTART:$now.-8:T200000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename1:;RSVP=TRUE:$rcuaddrurn1:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:TRANSPARENT
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/3.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite1/3.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/3.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/3.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,19 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:event-1
+DTSTART:$now.-8:T200000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename1:;RSVP=TRUE:$rcuaddrurn1:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:TRANSPARENT
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/4.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite1/4.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/4.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,19 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
-BEGIN:VEVENT
-UID:event-1
-DTSTART:$now.-8:T200000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename1:;RSVP=TRUE:$rcuaddrurn1:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:TRANSPARENT
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/4.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite1/4.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/4.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite1/4.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,19 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:event-1
+DTSTART:$now.-8:T200000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename1:;RSVP=TRUE:$rcuaddrurn1:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:TRANSPARENT
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/1.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite2/1.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/1.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,36 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Example Inc.//Example Calendar//EN
-BEGIN:VEVENT
-UID:event-2
-DTSTART:$now.-9:T210000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddralt1:
-ATTENDEE;CN=$username2:;RSVP=TRUE:$cuaddralt2:
-ATTENDEE;CN=$resourcename1::$rcuaddralt1:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1::$cuaddralt1:
-RRULE:FREQ=DAILY;COUNT=5
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:OPAQUE
-END:VEVENT
-BEGIN:VEVENT
-UID:event-2
-RECURRENCE-ID:$now.-8:T210000Z
-DTSTART:$now.-8:T200000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddralt1:
-ATTENDEE;CN=$username2:;RSVP=TRUE:$cuaddralt2:
-ATTENDEE;CN=$resourcename1::$rcuaddralt1:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1::$cuaddralt1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:OPAQUE
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/1.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite2/1.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/1.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/1.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,36 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Example Inc.//Example Calendar//EN
+BEGIN:VEVENT
+UID:event-2
+DTSTART:$now.-9:T210000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddralt1:
+ATTENDEE;CN=$username2:;RSVP=TRUE:$cuaddralt2:
+ATTENDEE;CN=$resourcename1::$rcuaddralt1:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1::$cuaddralt1:
+RRULE:FREQ=DAILY;COUNT=5
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:OPAQUE
+END:VEVENT
+BEGIN:VEVENT
+UID:event-2
+RECURRENCE-ID:$now.-8:T210000Z
+DTSTART:$now.-8:T200000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddralt1:
+ATTENDEE;CN=$username2:;RSVP=TRUE:$cuaddralt2:
+ATTENDEE;CN=$resourcename1::$rcuaddralt1:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1::$cuaddralt1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/2.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite2/2.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/2.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,36 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Example Inc.//Example Calendar//EN
-BEGIN:VEVENT
-UID:event-2
-DTSTART:$now.-9:T210000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename1:;RSVP=TRUE;SCHEDULE-STATUS=1.2:$rcuaddrurn1:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-RRULE:FREQ=DAILY;COUNT=5
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:OPAQUE
-END:VEVENT
-BEGIN:VEVENT
-UID:event-2
-RECURRENCE-ID:$now.-8:T210000Z
-DTSTART:$now.-8:T200000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename1:;RSVP=TRUE;SCHEDULE-STATUS=1.2:$rcuaddrurn1:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:OPAQUE
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/2.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite2/2.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/2.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/2.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,36 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Example Inc.//Example Calendar//EN
+BEGIN:VEVENT
+UID:event-2
+DTSTART:$now.-9:T210000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename1:;RSVP=TRUE;SCHEDULE-STATUS=1.2:$rcuaddrurn1:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+RRULE:FREQ=DAILY;COUNT=5
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:OPAQUE
+END:VEVENT
+BEGIN:VEVENT
+UID:event-2
+RECURRENCE-ID:$now.-8:T210000Z
+DTSTART:$now.-8:T200000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename1:;RSVP=TRUE;SCHEDULE-STATUS=1.2:$rcuaddrurn1:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/3.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite2/3.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/3.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,36 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
-BEGIN:VEVENT
-UID:event-2
-DTSTART:$now.-9:T210000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename1:;RSVP=TRUE:$rcuaddrurn1:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-RRULE:FREQ=DAILY;COUNT=5
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:TRANSPARENT
-END:VEVENT
-BEGIN:VEVENT
-UID:event-2
-RECURRENCE-ID:$now.-8:T210000Z
-DTSTART:$now.-8:T200000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename1:;RSVP=TRUE:$rcuaddrurn1:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:TRANSPARENT
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/3.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite2/3.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/3.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/3.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,36 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:event-2
+DTSTART:$now.-9:T210000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename1:;RSVP=TRUE:$rcuaddrurn1:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+RRULE:FREQ=DAILY;COUNT=5
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:TRANSPARENT
+END:VEVENT
+BEGIN:VEVENT
+UID:event-2
+RECURRENCE-ID:$now.-8:T210000Z
+DTSTART:$now.-8:T200000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename1:;RSVP=TRUE:$rcuaddrurn1:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:TRANSPARENT
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/4.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite2/4.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/4.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,36 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
-BEGIN:VEVENT
-UID:event-2
-DTSTART:$now.-9:T210000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename1:;RSVP=TRUE:$rcuaddrurn1:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-RRULE:FREQ=DAILY;COUNT=5
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:TRANSPARENT
-END:VEVENT
-BEGIN:VEVENT
-UID:event-2
-RECURRENCE-ID:$now.-8:T210000Z
-DTSTART:$now.-8:T200000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename1:;RSVP=TRUE:$rcuaddrurn1:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:TRANSPARENT
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/4.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite2/4.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/4.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite2/4.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,36 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:event-2
+DTSTART:$now.-9:T210000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename1:;RSVP=TRUE:$rcuaddrurn1:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+RRULE:FREQ=DAILY;COUNT=5
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:TRANSPARENT
+END:VEVENT
+BEGIN:VEVENT
+UID:event-2
+RECURRENCE-ID:$now.-8:T210000Z
+DTSTART:$now.-8:T200000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename1:;RSVP=TRUE:$rcuaddrurn1:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:TRANSPARENT
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/1.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite3/1.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/1.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,36 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Example Inc.//Example Calendar//EN
-BEGIN:VEVENT
-UID:event-3
-DTSTART:$now.-12:T210000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddralt1:
-ATTENDEE;CN=$username2:;RSVP=TRUE:$cuaddralt2:
-ATTENDEE;CN=$resourcename1::$rcuaddralt1:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1::$cuaddralt1:
-RRULE:FREQ=WEEKLY;COUNT=5
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:OPAQUE
-END:VEVENT
-BEGIN:VEVENT
-UID:event-3
-RECURRENCE-ID:$now.-5:T210000Z
-DTSTART:$now.-5:T200000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddralt1:
-ATTENDEE;CN=$username2:;RSVP=TRUE:$cuaddralt2:
-ATTENDEE;CN=$resourcename1::$rcuaddralt1:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1::$cuaddralt1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:OPAQUE
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/1.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite3/1.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/1.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/1.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,36 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Example Inc.//Example Calendar//EN
+BEGIN:VEVENT
+UID:event-3
+DTSTART:$now.-12:T210000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddralt1:
+ATTENDEE;CN=$username2:;RSVP=TRUE:$cuaddralt2:
+ATTENDEE;CN=$resourcename1::$rcuaddralt1:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1::$cuaddralt1:
+RRULE:FREQ=WEEKLY;COUNT=5
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:OPAQUE
+END:VEVENT
+BEGIN:VEVENT
+UID:event-3
+RECURRENCE-ID:$now.-5:T210000Z
+DTSTART:$now.-5:T200000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddralt1:
+ATTENDEE;CN=$username2:;RSVP=TRUE:$cuaddralt2:
+ATTENDEE;CN=$resourcename1::$rcuaddralt1:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1::$cuaddralt1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/2.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite3/2.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/2.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,52 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//Example Inc.//Example Calendar//EN
-BEGIN:VEVENT
-UID:event-3
-DTSTART:$now.-12:T210000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename1:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0:$rcuaddrurn1:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-RRULE:FREQ=WEEKLY;COUNT=5
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:OPAQUE
-END:VEVENT
-BEGIN:VEVENT
-UID:event-3
-RECURRENCE-ID:$now.-12:T210000Z
-DTSTART:$now.-12:T210000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename1:;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=2.0:$rcuaddrurn1:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:OPAQUE
-END:VEVENT
-BEGIN:VEVENT
-UID:event-3
-RECURRENCE-ID:$now.-5:T210000Z
-DTSTART:$now.-5:T200000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename1:;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;SCHEDULE-STATUS=2.0:$rcuaddrurn1:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:OPAQUE
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/2.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite3/2.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/2.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/2.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,52 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Example Inc.//Example Calendar//EN
+BEGIN:VEVENT
+UID:event-3
+DTSTART:$now.-12:T210000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename1:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0:$rcuaddrurn1:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+RRULE:FREQ=WEEKLY;COUNT=5
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:OPAQUE
+END:VEVENT
+BEGIN:VEVENT
+UID:event-3
+RECURRENCE-ID:$now.-12:T210000Z
+DTSTART:$now.-12:T210000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename1:;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=2.0:$rcuaddrurn1:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:OPAQUE
+END:VEVENT
+BEGIN:VEVENT
+UID:event-3
+RECURRENCE-ID:$now.-5:T210000Z
+DTSTART:$now.-5:T200000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename1:;PARTSTAT=NEEDS-ACTION;RSVP=TRUE;SCHEDULE-STATUS=2.0:$rcuaddrurn1:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/3.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite3/3.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/3.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,52 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
-BEGIN:VEVENT
-UID:event-3
-DTSTART:$now.-12:T210000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename1:;PARTSTAT=ACCEPTED:$rcuaddrurn1:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-RRULE:FREQ=WEEKLY;COUNT=5
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:TRANSPARENT
-END:VEVENT
-BEGIN:VEVENT
-UID:event-3
-RECURRENCE-ID:$now.-12:T210000Z
-DTSTART:$now.-12:T210000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename1:;PARTSTAT=NEEDS-ACTION:$rcuaddrurn1:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:TRANSPARENT
-END:VEVENT
-BEGIN:VEVENT
-UID:event-3
-RECURRENCE-ID:$now.-5:T210000Z
-DTSTART:$now.-5:T200000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename1:;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:$rcuaddrurn1:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:TRANSPARENT
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/3.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite3/3.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/3.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/3.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,52 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:event-3
+DTSTART:$now.-12:T210000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename1:;PARTSTAT=ACCEPTED:$rcuaddrurn1:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+RRULE:FREQ=WEEKLY;COUNT=5
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:TRANSPARENT
+END:VEVENT
+BEGIN:VEVENT
+UID:event-3
+RECURRENCE-ID:$now.-12:T210000Z
+DTSTART:$now.-12:T210000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename1:;PARTSTAT=NEEDS-ACTION:$rcuaddrurn1:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:TRANSPARENT
+END:VEVENT
+BEGIN:VEVENT
+UID:event-3
+RECURRENCE-ID:$now.-5:T210000Z
+DTSTART:$now.-5:T200000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename1:;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:$rcuaddrurn1:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:TRANSPARENT
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/4.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite3/4.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/4.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,52 +0,0 @@
-BEGIN:VCALENDAR
-VERSION:2.0
-PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
-BEGIN:VEVENT
-UID:event-3
-DTSTART:$now.-12:T210000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename1:;PARTSTAT=ACCEPTED:$rcuaddrurn1:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
-RRULE:FREQ=WEEKLY;COUNT=5
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:OPAQUE
-END:VEVENT
-BEGIN:VEVENT
-UID:event-3
-RECURRENCE-ID:$now.-12:T210000Z
-DTSTART:$now.-12:T210000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename1:;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:$rcuaddrurn1:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:TRANSPARENT
-END:VEVENT
-BEGIN:VEVENT
-UID:event-3
-RECURRENCE-ID:$now.-5:T210000Z
-DTSTART:$now.-5:T200000Z
-DURATION:PT1H
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
-ATTENDEE;CN=$resourcename1:;RSVP=TRUE:$rcuaddrurn1:
-CREATED:20060110T231240Z
-DESCRIPTION:Call-in
-DTSTAMP:20060309T185105Z
-ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
-STATUS:CONFIRMED
-SUMMARY:Example
-TRANSP:TRANSPARENT
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/4.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/autopast/suite3/4.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/4.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/autopast/suite3/4.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,52 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:event-3
+DTSTART:$now.-12:T210000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename1:;PARTSTAT=ACCEPTED:$rcuaddrurn1:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
+RRULE:FREQ=WEEKLY;COUNT=5
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:OPAQUE
+END:VEVENT
+BEGIN:VEVENT
+UID:event-3
+RECURRENCE-ID:$now.-12:T210000Z
+DTSTART:$now.-12:T210000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename1:;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:$rcuaddrurn1:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:TRANSPARENT
+END:VEVENT
+BEGIN:VEVENT
+UID:event-3
+RECURRENCE-ID:$now.-5:T210000Z
+DTSTART:$now.-5:T200000Z
+DURATION:PT1H
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;EMAIL=$email2::$cuaddrurn2:
+ATTENDEE;CN=$resourcename1:;RSVP=TRUE:$rcuaddrurn1:
+CREATED:20060110T231240Z
+DESCRIPTION:Call-in
+DTSTAMP:20060309T185105Z
+ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
+STATUS:CONFIRMED
+SUMMARY:Example
+TRANSP:TRANSPARENT
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/1.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/recur2/override_remove/1.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/1.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,47 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
-DURATION:PT1H
-SUMMARY:event 2
-UID:event2 at ninevah.local
-ORGANIZER;CN=$username1::$cuaddr1:
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddr1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:$cuaddr2:
-RRULE:FREQ=DAILY;COUNT=5
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0102T110000
-DURATION:PT1H
-SUMMARY:event 2
-UID:event2 at ninevah.local
-ORGANIZER;CN=$username1::$cuaddr1:
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddr1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:$cuaddr2:
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/1.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/recur2/override_remove/1.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/1.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/1.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,47 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
+DURATION:PT1H
+SUMMARY:event 2
+UID:event2 at ninevah.local
+ORGANIZER;CN=$username1::$cuaddr1:
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddr1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:$cuaddr2:
+RRULE:FREQ=DAILY;COUNT=5
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0102T110000
+DURATION:PT1H
+SUMMARY:event 2
+UID:event2 at ninevah.local
+ORGANIZER;CN=$username1::$cuaddr1:
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddr1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION:$cuaddr2:
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/2.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/recur2/override_remove/2.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/2.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,47 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
-DURATION:PT1H
-SUMMARY:event 2
-UID:event2 at ninevah.local
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
-RRULE:FREQ=DAILY;COUNT=5
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0102T110000
-DURATION:PT1H
-SUMMARY:event 2
-UID:event2 at ninevah.local
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/2.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/recur2/override_remove/2.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/2.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/2.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,47 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
+DURATION:PT1H
+SUMMARY:event 2
+UID:event2 at ninevah.local
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
+RRULE:FREQ=DAILY;COUNT=5
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0102T110000
+DURATION:PT1H
+SUMMARY:event 2
+UID:event2 at ninevah.local
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/3.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/recur2/override_remove/3.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/3.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,49 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
-DURATION:PT1H
-SUMMARY:event 2
-UID:event2 at ninevah.local
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email2::$cuaddrurn2:
-RRULE:FREQ=DAILY;COUNT=5
-TRANSP:TRANSPARENT
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0102T110000
-DURATION:PT1H
-SUMMARY:event 2
-UID:event2 at ninevah.local
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email2::$cuaddrurn2:
-TRANSP:TRANSPARENT
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/3.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/recur2/override_remove/3.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/3.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/3.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,49 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
+DURATION:PT1H
+SUMMARY:event 2
+UID:event2 at ninevah.local
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email2::$cuaddrurn2:
+RRULE:FREQ=DAILY;COUNT=5
+TRANSP:TRANSPARENT
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0102T110000
+DURATION:PT1H
+SUMMARY:event 2
+UID:event2 at ninevah.local
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email2::$cuaddrurn2:
+TRANSP:TRANSPARENT
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/4.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/recur2/override_remove/4.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/4.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,49 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
-DURATION:PT1H
-SUMMARY:event 2
-UID:event2 at ninevah.local
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
-RRULE:FREQ=DAILY;COUNT=5
-TRANSP:TRANSPARENT
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0102T110000
-DURATION:PT1H
-SUMMARY:event 2
-UID:event2 at ninevah.local
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
-TRANSP:TRANSPARENT
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/4.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/recur2/override_remove/4.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/4.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/4.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,49 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
+DURATION:PT1H
+SUMMARY:event 2
+UID:event2 at ninevah.local
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
+RRULE:FREQ=DAILY;COUNT=5
+TRANSP:TRANSPARENT
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0102T110000
+DURATION:PT1H
+SUMMARY:event 2
+UID:event2 at ninevah.local
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
+TRANSP:TRANSPARENT
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/5.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/recur2/override_remove/5.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/5.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,47 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
-DURATION:PT1H
-SUMMARY:event 2
-UID:event2 at ninevah.local
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0;EMAIL=$email2::$cuaddrurn2:
-RRULE:FREQ=DAILY;COUNT=5
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0102T110000
-DURATION:PT1H
-SUMMARY:event 2
-UID:event2 at ninevah.local
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0;EMAIL=$email2::$cuaddrurn2:
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/5.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/recur2/override_remove/5.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/5.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/5.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,47 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
+DURATION:PT1H
+SUMMARY:event 2
+UID:event2 at ninevah.local
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0;EMAIL=$email2::$cuaddrurn2:
+RRULE:FREQ=DAILY;COUNT=5
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0102T110000
+DURATION:PT1H
+SUMMARY:event 2
+UID:event2 at ninevah.local
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0;EMAIL=$email2::$cuaddrurn2:
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/6.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/recur2/override_remove/6.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/6.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,35 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
-DURATION:PT1H
-SUMMARY:event 2
-UID:event2 at ninevah.local
-ORGANIZER;CN=$username1::$cuaddr1:
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddr1:
-ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED:$cuaddr2:
-RRULE:FREQ=DAILY;COUNT=5
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/6.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/recur2/override_remove/6.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/6.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/6.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,35 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
+DURATION:PT1H
+SUMMARY:event 2
+UID:event2 at ninevah.local
+ORGANIZER;CN=$username1::$cuaddr1:
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED:$cuaddr1:
+ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED:$cuaddr2:
+RRULE:FREQ=DAILY;COUNT=5
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/7.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/recur2/override_remove/7.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/7.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,49 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
-DURATION:PT1H
-SUMMARY:event 2
-UID:event2 at ninevah.local
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
-RRULE:FREQ=DAILY;COUNT=5
-SEQUENCE:1
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0102T100000
-DURATION:PT1H
-SUMMARY:event 2
-UID:event2 at ninevah.local
-ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
-SEQUENCE:1
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/7.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/recur2/override_remove/7.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/7.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/7.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,49 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
+DURATION:PT1H
+SUMMARY:event 2
+UID:event2 at ninevah.local
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
+RRULE:FREQ=DAILY;COUNT=5
+SEQUENCE:1
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0102T100000
+DURATION:PT1H
+SUMMARY:event 2
+UID:event2 at ninevah.local
+ORGANIZER;CN=$username1:;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;SCHEDULE-STATUS=1.2;EMAIL=$email2::$cuaddrurn2:
+SEQUENCE:1
+END:VEVENT
+END:VCALENDAR
Deleted: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/8.ics
===================================================================
--- CalDAVTester/trunk/Resource/CalDAV/implicit/recur2/override_remove/8.ics 2013-03-07 18:25:19 UTC (rev 10865)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/8.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,50 +0,0 @@
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-PRODID:-//Example Inc.//Example Calendar//EN
-VERSION:2.0
-BEGIN:VTIMEZONE
-LAST-MODIFIED:20040110T032845Z
-TZID:US/Eastern
-BEGIN:DAYLIGHT
-DTSTART:20000404T020000
-RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-BEGIN:STANDARD
-DTSTART:20001026T020000
-RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-END:VTIMEZONE
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
-DURATION:PT1H
-SUMMARY:event 2
-UID:event2 at ninevah.local
-ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
-RRULE:FREQ=DAILY;COUNT=5
-TRANSP:TRANSPARENT
-END:VEVENT
-BEGIN:VEVENT
-DTSTAMP:20051222T205953Z
-CREATED:20060101T150000Z
-RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
-DTSTART;TZID=US/Eastern:$now.year.1:0102T100000
-DURATION:PT1H
-SUMMARY:event 2
-UID:event2 at ninevah.local
-ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
-ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email2::$cuaddrurn2:
-SEQUENCE:1
-TRANSP:TRANSPARENT
-END:VEVENT
-END:VCALENDAR
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/8.ics (from rev 10865, CalDAVTester/trunk/Resource/CalDAV/implicit/recur2/override_remove/8.ics)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/8.ics (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/recur2/override_remove/8.ics 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,50 @@
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART;TZID=US/Eastern:$now.year.1:0101T100000
+DURATION:PT1H
+SUMMARY:event 2
+UID:event2 at ninevah.local
+ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;PARTSTAT=ACCEPTED;EMAIL=$email2::$cuaddrurn2:
+RRULE:FREQ=DAILY;COUNT=5
+TRANSP:TRANSPARENT
+END:VEVENT
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+RECURRENCE-ID;TZID=US/Eastern:$now.year.1:0102T100000
+DTSTART;TZID=US/Eastern:$now.year.1:0102T100000
+DURATION:PT1H
+SUMMARY:event 2
+UID:event2 at ninevah.local
+ORGANIZER;CN=$username1:;SCHEDULE-STATUS=1.2;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username1:;PARTSTAT=ACCEPTED;EMAIL=$email1::$cuaddrurn1:
+ATTENDEE;CN=$username2:;RSVP=TRUE;PARTSTAT=NEEDS-ACTION;EMAIL=$email2::$cuaddrurn2:
+SEQUENCE:1
+TRANSP:TRANSPARENT
+END:VEVENT
+END:VCALENDAR
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/schedulechanges/organizerchange/1.ics
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/implicit/schedulechanges/organizerchange/1.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/implicit/schedulechanges/1.ics:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/implicit/schedulechanges/1.ics:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/implicit/schedulechanges/organizerchange/1.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/implicit/schedulechanges/1.ics:2949-2989
/CalDAVTester/branches/users/cdaboo/location-partial-accept-3574/Resource/implicit/schedulechanges/1.ics:3575-3581
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/implicit/schedulechanges/1.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/implicit/schedulechanges/organizerchange/1.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/implicit/schedulechanges/organizerchange/1.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/implicit/schedulechanges/organizerchange/1.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/implicit/schedulechanges/organizerchange/1.ics:10010-10782
/CalDAVTester/trunk/Resource/implicit/schedulechanges/1.ics:2451,3035,3142,3165,3190,3405,3432
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/implicit/schedulechanges/organizerchange/1.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/implicit/schedulechanges/1.ics:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/implicit/schedulechanges/1.ics:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/implicit/schedulechanges/organizerchange/1.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/implicit/schedulechanges/1.ics:2949-2989
/CalDAVTester/branches/users/cdaboo/location-partial-accept-3574/Resource/implicit/schedulechanges/1.ics:3575-3581
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/implicit/schedulechanges/1.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/implicit/schedulechanges/organizerchange/1.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/implicit/schedulechanges/organizerchange/1.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/implicit/schedulechanges/organizerchange/1.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/implicit/schedulechanges/organizerchange/1.ics:10010-10865
/CalDAVTester/trunk/Resource/implicit/schedulechanges/1.ics:2451,3035,3142,3165,3190,3405,3432
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/schedulechanges/organizerchange/2.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/implicit/schedulechanges/organizerchange/2.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/implicit/schedulechanges/2.xml:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/implicit/schedulechanges/2.xml:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/implicit/schedulechanges/organizerchange/2.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/implicit/schedulechanges/2.xml:2949-2989
/CalDAVTester/branches/users/cdaboo/location-partial-accept-3574/Resource/implicit/schedulechanges/2.xml:3575-3581
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/implicit/schedulechanges/2.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/implicit/schedulechanges/organizerchange/2.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/implicit/schedulechanges/organizerchange/2.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/implicit/schedulechanges/organizerchange/2.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/implicit/schedulechanges/organizerchange/2.xml:10010-10782
/CalDAVTester/trunk/Resource/implicit/schedulechanges/2.xml:2451,3035,3142,3165,3190,3405,3432
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/implicit/schedulechanges/organizerchange/2.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/implicit/schedulechanges/2.xml:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/implicit/schedulechanges/2.xml:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/implicit/schedulechanges/organizerchange/2.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/implicit/schedulechanges/2.xml:2949-2989
/CalDAVTester/branches/users/cdaboo/location-partial-accept-3574/Resource/implicit/schedulechanges/2.xml:3575-3581
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/implicit/schedulechanges/2.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/implicit/schedulechanges/organizerchange/2.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/implicit/schedulechanges/organizerchange/2.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/implicit/schedulechanges/organizerchange/2.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/implicit/schedulechanges/organizerchange/2.xml:10010-10865
/CalDAVTester/trunk/Resource/implicit/schedulechanges/2.xml:2451,3035,3142,3165,3190,3405,3432
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/schedulechanges/organizerchange/3.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/implicit/schedulechanges/organizerchange/3.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/implicit/schedulechanges/3.xml:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/implicit/schedulechanges/3.xml:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/implicit/schedulechanges/organizerchange/3.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/implicit/schedulechanges/3.xml:2949-2989
/CalDAVTester/branches/users/cdaboo/location-partial-accept-3574/Resource/implicit/schedulechanges/3.xml:3575-3581
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/implicit/schedulechanges/3.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/implicit/schedulechanges/organizerchange/3.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/implicit/schedulechanges/organizerchange/3.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/implicit/schedulechanges/organizerchange/3.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/implicit/schedulechanges/organizerchange/3.xml:10010-10782
/CalDAVTester/trunk/Resource/implicit/schedulechanges/3.xml:2451,3035,3142,3165,3190,3405,3432
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/implicit/schedulechanges/organizerchange/3.xml:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/implicit/schedulechanges/3.xml:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/implicit/schedulechanges/3.xml:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/implicit/schedulechanges/organizerchange/3.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/implicit/schedulechanges/3.xml:2949-2989
/CalDAVTester/branches/users/cdaboo/location-partial-accept-3574/Resource/implicit/schedulechanges/3.xml:3575-3581
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/implicit/schedulechanges/3.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/implicit/schedulechanges/organizerchange/3.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/implicit/schedulechanges/organizerchange/3.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/implicit/schedulechanges/organizerchange/3.xml:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/implicit/schedulechanges/organizerchange/3.xml:10010-10865
/CalDAVTester/trunk/Resource/implicit/schedulechanges/3.xml:2451,3035,3142,3165,3190,3405,3432
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/schedulechanges/organizerchange/4.ics
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/implicit/schedulechanges/organizerchange/4.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/implicit/schedulechanges/4.ics:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/implicit/schedulechanges/4.ics:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/implicit/schedulechanges/organizerchange/4.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/implicit/schedulechanges/4.ics:2949-2989
/CalDAVTester/branches/users/cdaboo/location-partial-accept-3574/Resource/implicit/schedulechanges/4.ics:3575-3581
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/implicit/schedulechanges/4.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/implicit/schedulechanges/organizerchange/4.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/implicit/schedulechanges/organizerchange/4.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/implicit/schedulechanges/organizerchange/4.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/implicit/schedulechanges/organizerchange/4.ics:10010-10782
/CalDAVTester/trunk/Resource/implicit/schedulechanges/4.ics:2451,3035,3142,3165,3190,3405,3432
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/implicit/schedulechanges/organizerchange/4.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/implicit/schedulechanges/4.ics:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/implicit/schedulechanges/4.ics:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/implicit/schedulechanges/organizerchange/4.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/implicit/schedulechanges/4.ics:2949-2989
/CalDAVTester/branches/users/cdaboo/location-partial-accept-3574/Resource/implicit/schedulechanges/4.ics:3575-3581
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/implicit/schedulechanges/4.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/implicit/schedulechanges/organizerchange/4.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/implicit/schedulechanges/organizerchange/4.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/implicit/schedulechanges/organizerchange/4.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/implicit/schedulechanges/organizerchange/4.ics:10010-10865
/CalDAVTester/trunk/Resource/implicit/schedulechanges/4.ics:2451,3035,3142,3165,3190,3405,3432
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/schedulechanges/organizerchange/5.ics
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/implicit/schedulechanges/organizerchange/5.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/implicit/schedulechanges/5.ics:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/implicit/schedulechanges/5.ics:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/implicit/schedulechanges/organizerchange/5.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/implicit/schedulechanges/5.ics:2949-2989
/CalDAVTester/branches/users/cdaboo/location-partial-accept-3574/Resource/implicit/schedulechanges/5.ics:3575-3581
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/implicit/schedulechanges/5.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/implicit/schedulechanges/organizerchange/5.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/implicit/schedulechanges/organizerchange/5.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/implicit/schedulechanges/organizerchange/5.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/implicit/schedulechanges/organizerchange/5.ics:10010-10782
/CalDAVTester/trunk/Resource/implicit/schedulechanges/5.ics:2451,3035,3142,3165,3190,3405,3432
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/implicit/schedulechanges/organizerchange/5.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/implicit/schedulechanges/5.ics:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/implicit/schedulechanges/5.ics:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/implicit/schedulechanges/organizerchange/5.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/implicit/schedulechanges/5.ics:2949-2989
/CalDAVTester/branches/users/cdaboo/location-partial-accept-3574/Resource/implicit/schedulechanges/5.ics:3575-3581
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/implicit/schedulechanges/5.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/implicit/schedulechanges/organizerchange/5.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/implicit/schedulechanges/organizerchange/5.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/implicit/schedulechanges/organizerchange/5.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/implicit/schedulechanges/organizerchange/5.ics:10010-10865
/CalDAVTester/trunk/Resource/implicit/schedulechanges/5.ics:2451,3035,3142,3165,3190,3405,3432
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/schedulechanges/organizerchange/6.ics
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/implicit/schedulechanges/organizerchange/6.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/implicit/schedulechanges/6.ics:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/implicit/schedulechanges/6.ics:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/implicit/schedulechanges/organizerchange/6.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/implicit/schedulechanges/6.ics:2949-2989
/CalDAVTester/branches/users/cdaboo/location-partial-accept-3574/Resource/implicit/schedulechanges/6.ics:3575-3581
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/implicit/schedulechanges/6.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/implicit/schedulechanges/organizerchange/6.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/implicit/schedulechanges/organizerchange/6.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/implicit/schedulechanges/organizerchange/6.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/implicit/schedulechanges/organizerchange/6.ics:10010-10782
/CalDAVTester/trunk/Resource/implicit/schedulechanges/6.ics:2451,3035,3142,3165,3190,3405,3432
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/implicit/schedulechanges/organizerchange/6.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/implicit/schedulechanges/6.ics:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/implicit/schedulechanges/6.ics:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/implicit/schedulechanges/organizerchange/6.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/implicit/schedulechanges/6.ics:2949-2989
/CalDAVTester/branches/users/cdaboo/location-partial-accept-3574/Resource/implicit/schedulechanges/6.ics:3575-3581
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/implicit/schedulechanges/6.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/implicit/schedulechanges/organizerchange/6.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/implicit/schedulechanges/organizerchange/6.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/implicit/schedulechanges/organizerchange/6.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/implicit/schedulechanges/organizerchange/6.ics:10010-10865
/CalDAVTester/trunk/Resource/implicit/schedulechanges/6.ics:2451,3035,3142,3165,3190,3405,3432
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/schedulechanges/organizerchange/7.ics
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/implicit/schedulechanges/organizerchange/7.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/implicit/schedulechanges/7.ics:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/implicit/schedulechanges/7.ics:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/implicit/schedulechanges/organizerchange/7.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/implicit/schedulechanges/7.ics:2949-2989
/CalDAVTester/branches/users/cdaboo/location-partial-accept-3574/Resource/implicit/schedulechanges/7.ics:3575-3581
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/implicit/schedulechanges/7.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/implicit/schedulechanges/organizerchange/7.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/implicit/schedulechanges/organizerchange/7.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/implicit/schedulechanges/organizerchange/7.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/implicit/schedulechanges/organizerchange/7.ics:10010-10782
/CalDAVTester/trunk/Resource/implicit/schedulechanges/7.ics:2451,3035,3142,3165,3190,3405,3432
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/implicit/schedulechanges/organizerchange/7.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/implicit/schedulechanges/7.ics:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/implicit/schedulechanges/7.ics:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/implicit/schedulechanges/organizerchange/7.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/implicit/schedulechanges/7.ics:2949-2989
/CalDAVTester/branches/users/cdaboo/location-partial-accept-3574/Resource/implicit/schedulechanges/7.ics:3575-3581
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/implicit/schedulechanges/7.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/implicit/schedulechanges/organizerchange/7.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/implicit/schedulechanges/organizerchange/7.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/implicit/schedulechanges/organizerchange/7.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/implicit/schedulechanges/organizerchange/7.ics:10010-10865
/CalDAVTester/trunk/Resource/implicit/schedulechanges/7.ics:2451,3035,3142,3165,3190,3405,3432
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/Resource/CalDAV/implicit/schedulechanges/organizerchange/8.ics
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/implicit/schedulechanges/organizerchange/8.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/implicit/schedulechanges/8.ics:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/implicit/schedulechanges/8.ics:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/implicit/schedulechanges/organizerchange/8.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/implicit/schedulechanges/8.ics:2949-2989
/CalDAVTester/branches/users/cdaboo/location-partial-accept-3574/Resource/implicit/schedulechanges/8.ics:3575-3581
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/implicit/schedulechanges/8.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/implicit/schedulechanges/organizerchange/8.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/implicit/schedulechanges/organizerchange/8.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/implicit/schedulechanges/organizerchange/8.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/implicit/schedulechanges/organizerchange/8.ics:10010-10782
/CalDAVTester/trunk/Resource/implicit/schedulechanges/8.ics:2451,3035,3142,3165,3190,3405,3432
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/Resource/CalDAV/implicit/schedulechanges/organizerchange/8.ics:7584
/CalDAVTester/branches/users/cdaboo/attendee-comments-2887/Resource/implicit/schedulechanges/8.ics:2888-2910
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/Resource/implicit/schedulechanges/8.ics:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/Resource/CalDAV/implicit/schedulechanges/organizerchange/8.ics:8221-8346
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/Resource/implicit/schedulechanges/8.ics:2949-2989
/CalDAVTester/branches/users/cdaboo/location-partial-accept-3574/Resource/implicit/schedulechanges/8.ics:3575-3581
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/Resource/implicit/schedulechanges/8.ics:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/Resource/CalDAV/implicit/schedulechanges/organizerchange/8.ics:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/Resource/CalDAV/implicit/schedulechanges/organizerchange/8.ics:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/Resource/CalDAV/implicit/schedulechanges/organizerchange/8.ics:5229-5440
/CalDAVTester/trunk/Resource/CalDAV/implicit/schedulechanges/organizerchange/8.ics:10010-10865
/CalDAVTester/trunk/Resource/implicit/schedulechanges/8.ics:2451,3035,3142,3165,3190,3405,3432
Modified: CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CalDAV/implicitattendeedelete.xml
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CalDAV/implicitattendeedelete.xml 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CalDAV/implicitattendeedelete.xml 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1649,6 +1649,572 @@
</test>
</test-suite>
+ <test-suite name='Recurring without master - delete of undeclined instance' ignore='no'>
+ <test name='1'>
+ <description>Organizer stores event</description>
+ <request print-response='no'>
+ <method>PUT</method>
+ <ruri>$calendarpath1:/1.ics</ruri>
+ <data>
+ <content-type>text/calendar; charset=utf-8</content-type>
+ <filepath>Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/1.ics</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='2'>
+ <description>Organizer checks data</description>
+ <request print-response='no'>
+ <method>GET</method>
+ <ruri>$calendarpath1:/1.ics</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/2.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='3'>
+ <description>Attendee 2 Inbox Item</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>WAITCOUNT 1</method>
+ <ruri>$inboxpath2:/</ruri>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>GETNEW</method>
+ <ruri>$inboxpath2:/</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>DELETE</method>
+ <ruri>$</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>204</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='4'>
+ <description>Attendee 2 -> Remove one</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>GETNEW</method>
+ <ruri>$calendarpath2:/</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>PUT</method>
+ <ruri>$</ruri>
+ <data>
+ <content-type>text/calendar; charset=utf-8</content-type>
+ <filepath>Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/3.ics</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ <graburi>$attendee2_event:</graburi>
+ </request>
+ </test>
+ <test name='5'>
+ <description>Organizer Inbox Item</description>
+ <request print-response='no'>
+ <method>WAITCOUNT 1</method>
+ <ruri>$inboxpath1:/</ruri>
+ </request>
+ <request print-response='no'>
+ <method>GETNEW</method>
+ <ruri>$inboxpath1:/</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request print-response='no'>
+ <method>DELETE</method>
+ <ruri>$</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>204</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='6'>
+ <description>Organizer data changed</description>
+ <request print-response='no'>
+ <method>GET</method>
+ <ruri>$calendarpath1:/1.ics</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/4.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='7'>
+ <description>Attendee 2 -> accept remaining instance</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>PUT</method>
+ <ruri>$attendee2_event:</ruri>
+ <data>
+ <content-type>text/calendar; charset=utf-8</content-type>
+ <filepath>Resource/CalDAV/implicit/attendeedelete/recurring-no-master/5.ics</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='8'>
+ <description>Organizer Inbox Item</description>
+ <request print-response='no'>
+ <method>WAITCOUNT 1</method>
+ <ruri>$inboxpath1:/</ruri>
+ </request>
+ <request print-response='no'>
+ <method>GETNEW</method>
+ <ruri>$inboxpath1:/</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request print-response='no'>
+ <method>DELETE</method>
+ <ruri>$</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>204</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='9'>
+ <description>Organizer changes subject</description>
+ <request user="$userid3:" pswd="$pswd3:">
+ <method>DELETEALL</method>
+ <ruri>$inboxpath3:/</ruri>
+ </request>
+ <request print-response='no'>
+ <method>PUT</method>
+ <ruri>$calendarpath1:/1.ics</ruri>
+ <data>
+ <content-type>text/calendar; charset=utf-8</content-type>
+ <filepath>Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/6.ics</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='10'>
+ <description>Attendee 3 Inbox Item</description>
+ <request user="$userid3:" pswd="$pswd3:" print-response='no'>
+ <method>WAITCOUNT 1</method>
+ <ruri>$inboxpath3:/</ruri>
+ </request>
+ <request user="$userid3:" pswd="$pswd3:" print-response='no'>
+ <method>GETNEW</method>
+ <ruri>$inboxpath3:/</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request user="$userid3:" pswd="$pswd3:" print-response='no'>
+ <method>DELETE</method>
+ <ruri>$</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>204</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='11'>
+ <description>Attendee 3 has data</description>
+ <request user="$userid3:" pswd="$pswd3:" print-response='no'>
+ <method>GETNEW</method>
+ <ruri>$calendarpath3:/</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/7.ics</value>
+ </arg>
+ </verify>
+ <graburi>$attendee3_event:</graburi>
+ </request>
+ </test>
+ <test name='12'>
+ <description>Attendee 2 Inbox Item</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>WAITCOUNT 1</method>
+ <ruri>$inboxpath2:/</ruri>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>GETNEW</method>
+ <ruri>$inboxpath2:/</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>DELETE</method>
+ <ruri>$</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>204</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='13'>
+ <description>Attendee 2 has data</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>GET</method>
+ <ruri>$attendee2_event:</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/8.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='14'>
+ <description>Attendee 3 -> Accepted</description>
+ <request user="$userid3:" pswd="$pswd3:" print-response='no'>
+ <method>PUT</method>
+ <ruri>$attendee3_event:</ruri>
+ <data>
+ <content-type>text/calendar; charset=utf-8</content-type>
+ <filepath>Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/9.ics</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='15'>
+ <description>Organizer Inbox Item</description>
+ <request print-response='no'>
+ <method>WAITCOUNT 1</method>
+ <ruri>$inboxpath1:/</ruri>
+ </request>
+ <request print-response='no'>
+ <method>GETNEW</method>
+ <ruri>$inboxpath1:/</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request print-response='no'>
+ <method>DELETE</method>
+ <ruri>$</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>204</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='16'>
+ <description>Organizer data changed</description>
+ <request print-response='no'>
+ <method>GET</method>
+ <ruri>$calendarpath1:/1.ics</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/10.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='17'>
+ <description>Attendee 2 No Inbox Item</description>
+ <request print-response='no'>
+ <method>DELAY</method>
+ <ruri>1</ruri>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:" print-response="no">
+ <method>PROPFIND</method>
+ <ruri>$inboxpath2:/</ruri>
+ <header>
+ <name>Depth</name>
+ <value>1</value>
+ </header>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/PROPFIND/count.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>count</name>
+ <value>0</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='18'>
+ <description>Attendee 2 has data</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>GET</method>
+ <ruri>$attendee2_event:</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/11.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='19'>
+ <description>Organizer changes time of declined instance</description>
+ <request user="$userid3:" pswd="$pswd3:">
+ <method>DELETEALL</method>
+ <ruri>$inboxpath3:/</ruri>
+ </request>
+ <request print-response='no'>
+ <method>PUT</method>
+ <ruri>$calendarpath1:/1.ics</ruri>
+ <data>
+ <content-type>text/calendar; charset=utf-8</content-type>
+ <filepath>Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/12.ics</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='20'>
+ <description>Attendee 3 Inbox Item</description>
+ <request user="$userid3:" pswd="$pswd3:" print-response='no'>
+ <method>WAITCOUNT 1</method>
+ <ruri>$inboxpath3:/</ruri>
+ </request>
+ <request user="$userid3:" pswd="$pswd3:" print-response='no'>
+ <method>GETNEW</method>
+ <ruri>$inboxpath3:/</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request user="$userid3:" pswd="$pswd3:" print-response='no'>
+ <method>DELETE</method>
+ <ruri>$</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>204</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='21'>
+ <description>Attendee 3 has data</description>
+ <request user="$userid3:" pswd="$pswd3:" print-response='no'>
+ <method>GET</method>
+ <ruri>$attendee3_event:</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/13.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='22'>
+ <description>Attendee 2 Inbox Item</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>WAITCOUNT 1</method>
+ <ruri>$inboxpath2:/</ruri>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>GETNEW</method>
+ <ruri>$inboxpath2:/</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>DELETE</method>
+ <ruri>$</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>204</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='23'>
+ <description>Attendee 2 has data</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>GET</method>
+ <ruri>$attendee2_event:</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/14.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='24'>
+ <description>Attendee 2 -> DELETE</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>DELETE</method>
+ <ruri>$attendee2_event:</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='25'>
+ <description>Organizer Inbox Item</description>
+ <request print-response='no'>
+ <method>WAITCOUNT 1</method>
+ <ruri>$inboxpath1:/</ruri>
+ </request>
+ <request print-response='no'>
+ <method>GETNEW</method>
+ <ruri>$inboxpath1:/</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request print-response='no'>
+ <method>DELETE</method>
+ <ruri>$</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>204</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='26'>
+ <description>Organizer data changed</description>
+ <request print-response='no'>
+ <method>GET</method>
+ <ruri>$calendarpath1:/1.ics</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/15.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='27'>
+ <description>Organizer changes time of one declined instance, summary of other</description>
+ <request user="$userid3:" pswd="$pswd3:">
+ <method>DELETEALL</method>
+ <ruri>$inboxpath3:/</ruri>
+ </request>
+ <request print-response='no'>
+ <method>PUT</method>
+ <ruri>$calendarpath1:/1.ics</ruri>
+ <data>
+ <content-type>text/calendar; charset=utf-8</content-type>
+ <filepath>Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/16.ics</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='28'>
+ <description>Attendee 2 Inbox Item</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>WAITCOUNT 1</method>
+ <ruri>$inboxpath2:/</ruri>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>GETNEW</method>
+ <ruri>$inboxpath2:/</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>DELETE</method>
+ <ruri>$</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>204</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='29'>
+ <description>Attendee 2 has data</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>GETNEW</method>
+ <ruri>$calendarpath2:/</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/attendeedelete/recurring-delete-instance/17.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='-1'>
+ <description>Clean-up</description>
+ <request user="$userid1:" pswd="$pswd1:">
+ <method>DELETEALL</method>
+ <ruri>$calendarpath1:/</ruri>
+ <ruri>$inboxpath1:/</ruri>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:">
+ <method>DELETEALL</method>
+ <ruri>$calendarpath2:/</ruri>
+ <ruri>$inboxpath2:/</ruri>
+ </request>
+ <request user="$userid3:" pswd="$pswd3:">
+ <method>DELETEALL</method>
+ <ruri>$calendarpath3:/</ruri>
+ <ruri>$inboxpath3:/</ruri>
+ </request>
+ </test>
+ </test-suite>
+
<end/>
</caldavtest>
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CalDAV/implicitauto10.xml (from rev 10865, CalDAVTester/trunk/scripts/tests/CalDAV/implicitauto10.xml)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CalDAV/implicitauto10.xml (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CalDAV/implicitauto10.xml 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,539 @@
+<?xml version="1.0" standalone="no"?>
+
+<!DOCTYPE caldavtest SYSTEM "caldavtest.dtd">
+
+<!--
+ Copyright (c) 2013 Apple Inc. All rights reserved.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<caldavtest>
+ <description>Test implicit scheduling for auto-accept location where change occurs during attendee refresh</description>
+
+ <require-feature>
+ <feature>caldav</feature>
+ <feature>auto-accept</feature>
+ <feature>implicit-scheduling</feature>
+ </require-feature>
+
+ <start>
+ <request user="$userid1:" pswd="$pswd1:">
+ <method>GET</method>
+ <ruri>$calendarpath1:/</ruri>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:">
+ <method>GET</method>
+ <ruri>$calendarpath2:/</ruri>
+ </request>
+ <request>
+ <method>DELETEALL</method>
+ <ruri>$inboxpath1:/</ruri>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:">
+ <method>DELETEALL</method>
+ <ruri>$inboxpath2:/</ruri>
+ </request>
+ <request user="$useradmin:" pswd="$pswdadmin:">
+ <method>DELETEALL</method>
+ <ruri>$rinboxpath8:/</ruri>
+ </request>
+ <request user="$useradmin:" pswd="$pswdadmin:">
+ <method>DELETEALL</method>
+ <ruri>$rcalendarpath8:/</ruri>
+ </request>
+ </start>
+
+ <test-suite name='#1 Non-recurring' ignore='no'>
+ <test name='1' ignore='no'>
+ <description>Create new blocking event - just resource</description>
+ <request>
+ <method>PUT</method>
+ <ruri>$calendarpath1:/1.ics</ruri>
+ <data>
+ <content-type>text/calendar; charset=utf-8</content-type>
+ <filepath>Resource/CalDAV/implicit/auto10/suite1/1.ics</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request>
+ <method>WAITCOUNT 1</method>
+ <ruri>$inboxpath1:/</ruri>
+ </request>
+ </test>
+ <test name='2' ignore='no'>
+ <description>One item in user01 Inbox</description>
+ <request print-response="no">
+ <method>PROPFIND</method>
+ <ruri>$inboxpath1:/</ruri>
+ <header>
+ <name>Depth</name>
+ <value>1</value>
+ </header>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/PROPFIND/count.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>count</name>
+ <value>1</value>
+ </arg>
+ </verify>
+ </request>
+ <request>
+ <method>DELETEALL</method>
+ <ruri>$inboxpath1:/</ruri>
+ </request>
+ </test>
+ <test name='3' ignore='no'>
+ <description>One item in user01 Calendar</description>
+ <request print-response="no">
+ <method>GET</method>
+ <ruri>$calendarpath1:/1.ics</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/auto10/suite1/2.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='4' ignore='no'>
+ <description>No items in resource08 Inbox</description>
+ <request user="$useradmin:" pswd="$pswdadmin:" print-response="no">
+ <method>PROPFIND</method>
+ <ruri>$rinboxpath8:/</ruri>
+ <header>
+ <name>Depth</name>
+ <value>1</value>
+ </header>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/PROPFIND/count.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>count</name>
+ <value>0</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='5' ignore='no'>
+ <description>One item in resource08 Calendar</description>
+ <request user="$useradmin:" pswd="$pswdadmin:" print-response="no">
+ <method>GETNEW</method>
+ <ruri>$rcalendarpath8:/</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/auto10/suite1/3.ics</value>
+ </arg>
+ </verify>
+ <graburi>$r1:</graburi>
+ </request>
+ </test>
+ <test name='6' ignore='no'>
+ <description>Create new conflicting event with attendee</description>
+ <request>
+ <method>PUT</method>
+ <ruri>$calendarpath1:/2.ics</ruri>
+ <data>
+ <content-type>text/calendar; charset=utf-8</content-type>
+ <filepath>Resource/CalDAV/implicit/auto10/suite1/4.ics</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='7' ignore='no'>
+ <description>No item in user01 Inbox</description>
+ <request print-response="no">
+ <method>PROPFIND</method>
+ <ruri>$inboxpath1:/</ruri>
+ <header>
+ <name>Depth</name>
+ <value>1</value>
+ </header>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/PROPFIND/count.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>count</name>
+ <value>0</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='8' ignore='no'>
+ <description>One item in user01 Calendar</description>
+ <request print-response="no">
+ <method>GET</method>
+ <ruri>$calendarpath1:/2.ics</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/auto10/suite1/5.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='9' ignore='no'>
+ <description>One item in user02 Inbox</description>
+ <request user="$useradmin:" pswd="$pswdadmin:" print-response="no">
+ <method>PROPFIND</method>
+ <ruri>$inboxpath2:/</ruri>
+ <header>
+ <name>Depth</name>
+ <value>1</value>
+ </header>
+ <data>
+ <content-type>text/calendar; charset=utf-8</content-type>
+ <filepath>Resource/Common/PROPFIND/count.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>count</name>
+ <value>1</value>
+ </arg>
+ </verify>
+ </request>
+ <request>
+ <method>DELETEALL</method>
+ <ruri>$inboxpath1:/</ruri>
+ </request>
+ </test>
+ <test name='10' ignore='no'>
+ <description>One item in user02 calendar</description>
+ <request user="$useradmin:" pswd="$pswdadmin:" print-response="no">
+ <method>GETNEW</method>
+ <ruri>$calendarpath2:/</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/auto10/suite1/6.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='11' ignore='no'>
+ <description>One item in resource08 Inbox</description>
+ <request user="$useradmin:" pswd="$pswdadmin:" print-response="no">
+ <method>PROPFIND</method>
+ <ruri>$rinboxpath8:/</ruri>
+ <header>
+ <name>Depth</name>
+ <value>1</value>
+ </header>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/PROPFIND/count.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>count</name>
+ <value>1</value>
+ </arg>
+ </verify>
+ </request>
+ <request>
+ <method>DELETEALL</method>
+ <ruri>$rinboxpath8:/</ruri>
+ </request>
+ </test>
+ <test name='12' ignore='no'>
+ <description>One item in resource08 Calendar</description>
+ <request user="$useradmin:" pswd="$pswdadmin:" print-response="no">
+ <method>GETNEW</method>
+ <ruri>$rcalendarpath8:/</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/auto10/suite1/7.ics</value>
+ </arg>
+ </verify>
+ <graburi>$r2:</graburi>
+ </request>
+ </test>
+ <test name='13' ignore='no'>
+ <description>Cancel blocking event</description>
+ <request>
+ <method>DELETE</method>
+ <ruri>$calendarpath1:/1.ics</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='14' ignore='no'>
+ <description>No items in resource08 Inbox</description>
+ <request user="$useradmin:" pswd="$pswdadmin:" print-response="no">
+ <method>PROPFIND</method>
+ <ruri>$rinboxpath8:/</ruri>
+ <header>
+ <name>Depth</name>
+ <value>1</value>
+ </header>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/PROPFIND/count.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>count</name>
+ <value>0</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='15' ignore='no'>
+ <description>No item in resource08 Calendar</description>
+ <request user="$useradmin:" pswd="$pswdadmin:" print-response="no">
+ <method>GET</method>
+ <ruri>$r1:</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ <arg>
+ <name>status</name>
+ <value>404</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='16'>
+ <description>Attendee -> Accepted</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>GETNEW</method>
+ <ruri>$calendarpath2:/</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>PUT</method>
+ <ruri>$</ruri>
+ <data>
+ <content-type>text/calendar; charset=utf-8</content-type>
+ <filepath>Resource/CalDAV/implicit/auto10/suite1/8.ics</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request>
+ <method>DELAY</method>
+ <ruri>10</ruri>
+ </request>
+ <request>
+ <method>WAITCOUNT 2</method>
+ <ruri>$inboxpath1:/</ruri>
+ </request>
+ </test>
+ <test name='17' ignore='no'>
+ <description>Two items in user01 Inbox - one is reply from resource</description>
+ <request print-response="no">
+ <method>PROPFIND</method>
+ <ruri>$inboxpath1:/</ruri>
+ <header>
+ <name>Depth</name>
+ <value>1</value>
+ </header>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/PROPFIND/count.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>count</name>
+ <value>2</value>
+ </arg>
+ </verify>
+ </request>
+ <request>
+ <method>DELETEALL</method>
+ <ruri>$inboxpath1:/</ruri>
+ </request>
+ </test>
+ <test name='18' ignore='no'>
+ <description>One item in user01 Calendar</description>
+ <request print-response="no">
+ <method>GET</method>
+ <ruri>$calendarpath1:/2.ics</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/auto10/suite1/9.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='19' ignore='no'>
+ <description>One item in resource08 Calendar</description>
+ <request user="$useradmin:" pswd="$pswdadmin:" print-response="no">
+ <method>GET</method>
+ <ruri>$r2:</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/auto10/suite1/10.ics</value>
+ </arg>
+ </verify>
+ <graburi>$r2:</graburi>
+ </request>
+ </test>
+ <test name='20' ignore='no'>
+ <description>Re-create new blocking event</description>
+ <request>
+ <method>PUT</method>
+ <ruri>$calendarpath1:/1.ics</ruri>
+ <data>
+ <content-type>text/calendar; charset=utf-8</content-type>
+ <filepath>Resource/CalDAV/implicit/auto10/suite1/1.ics</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='21' ignore='no'>
+ <description>No item in user01 Inbox</description>
+ <request print-response="no">
+ <method>PROPFIND</method>
+ <ruri>$inboxpath1:/</ruri>
+ <header>
+ <name>Depth</name>
+ <value>1</value>
+ </header>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/PROPFIND/count.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>count</name>
+ <value>0</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='22' ignore='no'>
+ <description>One item in user01 Calendar</description>
+ <request print-response="no">
+ <method>GET</method>
+ <ruri>$calendarpath1:/1.ics</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/auto10/suite1/11.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='23' ignore='no'>
+ <description>One item in resource08 Inbox</description>
+ <request user="$useradmin:" pswd="$pswdadmin:" print-response="no">
+ <method>PROPFIND</method>
+ <ruri>$rinboxpath8:/</ruri>
+ <header>
+ <name>Depth</name>
+ <value>1</value>
+ </header>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/PROPFIND/count.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>count</name>
+ <value>1</value>
+ </arg>
+ </verify>
+ </request>
+ <request>
+ <method>DELETEALL</method>
+ <ruri>$rinboxpath8:/</ruri>
+ </request>
+ </test>
+ <test name='24' ignore='no'>
+ <description>One item in resource08 Calendar</description>
+ <request user="$useradmin:" pswd="$pswdadmin:" print-response="no">
+ <method>GETNEW</method>
+ <ruri>$rcalendarpath8:/</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/auto10/suite1/12.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='-1' ignore='no'>
+ <description>Clean-up inboxes</description>
+ <request>
+ <method>DELETEALL</method>
+ <ruri>$inboxpath1:/</ruri>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:">
+ <method>DELETEALL</method>
+ <ruri>$inboxpath2:/</ruri>
+ </request>
+ <request user="$useradmin:" pswd="$pswdadmin:">
+ <method>DELETEALL</method>
+ <ruri>$rinboxpath8:/</ruri>
+ </request>
+ </test>
+ </test-suite>
+
+ <end>
+ <request>
+ <method>DELETEALL</method>
+ <ruri>$inboxpath1:/</ruri>
+ <ruri>$calendarpath1:/</ruri>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:">
+ <method>DELETEALL</method>
+ <ruri>$inboxpath2:/</ruri>
+ <ruri>$calendarpath2:/</ruri>
+ </request>
+ <request user="$useradmin:" pswd="$pswdadmin:">
+ <method>DELETEALL</method>
+ <ruri>$rinboxpath8:/</ruri>
+ <ruri>$rcalendarpath8:/</ruri>
+ </request>
+ </end>
+
+</caldavtest>
Copied: CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CalDAV/implicitautopast.xml (from rev 10865, CalDAVTester/trunk/scripts/tests/CalDAV/implicitautopast.xml)
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CalDAV/implicitautopast.xml (rev 0)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CalDAV/implicitautopast.xml 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,504 @@
+<?xml version="1.0" standalone="no"?>
+
+<!DOCTYPE caldavtest SYSTEM "caldavtest.dtd">
+
+<!--
+ Copyright (c) 2006-2013 Apple Inc. All rights reserved.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<caldavtest>
+ <description>Test implicit scheduling for auto-accept location, with past event</description>
+
+ <require-feature>
+ <feature>caldav</feature>
+ <feature>auto-accept</feature>
+ <feature>implicit-scheduling</feature>
+ </require-feature>
+
+ <start>
+ <request user="$userid1:" pswd="$pswd1:">
+ <method>GET</method>
+ <ruri>$calendarpath1:/</ruri>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:">
+ <method>GET</method>
+ <ruri>$calendarpath2:/</ruri>
+ </request>
+ <request>
+ <method>DELETEALL</method>
+ <ruri>$inboxpath1:/</ruri>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:">
+ <method>DELETEALL</method>
+ <ruri>$inboxpath2:/</ruri>
+ </request>
+ <request user="$useradmin:" pswd="$pswdadmin:">
+ <method>DELETEALL</method>
+ <ruri>$rinboxpath1:/</ruri>
+ <ruri>$rcalendarpath1:/</ruri>
+ </request>
+ </start>
+
+ <test-suite name='#1 Non-recurring past event' ignore='no'>
+ <test name='1' ignore='no'>
+ <description>Create new event</description>
+ <request>
+ <method>PUT</method>
+ <ruri>$calendarpath1:/1.ics</ruri>
+ <data>
+ <content-type>text/calendar; charset=utf-8</content-type>
+ <filepath>Resource/CalDAV/implicit/autopast/suite1/1.ics</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request>
+ <method>DELAY</method>
+ <ruri>1</ruri>
+ </request>
+ </test>
+ <test name='2' ignore='no'>
+ <description>No item in user01 Inbox</description>
+ <request print-response="no">
+ <method>PROPFIND</method>
+ <ruri>$inboxpath1:/</ruri>
+ <header>
+ <name>Depth</name>
+ <value>1</value>
+ </header>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/PROPFIND/count.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>count</name>
+ <value>0</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='3' ignore='no'>
+ <description>One item in user01 Calendar</description>
+ <request print-response="no">
+ <method>GET</method>
+ <ruri>$calendarpath1:/1.ics</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/autopast/suite1/2.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='4' ignore='no'>
+ <description>One item in user02 Inbox</description>
+ <request user="$useradmin:" pswd="$pswdadmin:" print-response="no">
+ <method>PROPFIND</method>
+ <ruri>$inboxpath2:/</ruri>
+ <header>
+ <name>Depth</name>
+ <value>1</value>
+ </header>
+ <data>
+ <content-type>text/calendar; charset=utf-8</content-type>
+ <filepath>Resource/Common/PROPFIND/count.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>count</name>
+ <value>1</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='5' ignore='no'>
+ <description>One item in user02 calendar</description>
+ <request user="$useradmin:" pswd="$pswdadmin:" print-response="no">
+ <method>GETNEW</method>
+ <ruri>$calendarpath2:/</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/autopast/suite1/3.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='6' ignore='no'>
+ <description>No items in resource01 Inbox</description>
+ <request user="$useradmin:" pswd="$pswdadmin:" print-response="no">
+ <method>PROPFIND</method>
+ <ruri>$rinboxpath1:/</ruri>
+ <header>
+ <name>Depth</name>
+ <value>1</value>
+ </header>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/PROPFIND/count.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>count</name>
+ <value>0</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='7' ignore='no'>
+ <description>One item in resource01 Calendar</description>
+ <request user="$useradmin:" pswd="$pswdadmin:" print-response="no">
+ <method>GETNEW</method>
+ <ruri>$rcalendarpath1:/</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/autopast/suite1/4.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='8' ignore='no'>
+ <description>Clean-up inboxes</description>
+ <request>
+ <method>DELETEALL</method>
+ <ruri>$inboxpath1:/</ruri>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:">
+ <method>DELETEALL</method>
+ <ruri>$inboxpath2:/</ruri>
+ </request>
+ <request user="$useradmin:" pswd="$pswdadmin:">
+ <method>DELETEALL</method>
+ <ruri>$rinboxpath1:/</ruri>
+ </request>
+ </test>
+ </test-suite>
+
+ <test-suite name='#2 Recurring all in the past' ignore='no'>
+ <test name='1' ignore='no'>
+ <description>Create new event</description>
+ <request>
+ <method>PUT</method>
+ <ruri>$calendarpath1:/2.ics</ruri>
+ <data>
+ <content-type>text/calendar; charset=utf-8</content-type>
+ <filepath>Resource/CalDAV/implicit/autopast/suite2/1.ics</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request>
+ <method>DELAY</method>
+ <ruri>1</ruri>
+ </request>
+ </test>
+ <test name='2' ignore='no'>
+ <description>No item in user01 Inbox</description>
+ <request print-response="no">
+ <method>PROPFIND</method>
+ <ruri>$inboxpath1:/</ruri>
+ <header>
+ <name>Depth</name>
+ <value>1</value>
+ </header>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/PROPFIND/count.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>count</name>
+ <value>0</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='3' ignore='no'>
+ <description>One item in user01 Calendar</description>
+ <request print-response="no">
+ <method>GET</method>
+ <ruri>$calendarpath1:/2.ics</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/autopast/suite2/2.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='4' ignore='no'>
+ <description>One item in user02 Inbox</description>
+ <request user="$useradmin:" pswd="$pswdadmin:" print-response="no">
+ <method>PROPFIND</method>
+ <ruri>$inboxpath2:/</ruri>
+ <header>
+ <name>Depth</name>
+ <value>1</value>
+ </header>
+ <data>
+ <content-type>text/calendar; charset=utf-8</content-type>
+ <filepath>Resource/Common/PROPFIND/count.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>count</name>
+ <value>1</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='5' ignore='no'>
+ <description>One item in user02 calendar</description>
+ <request user="$useradmin:" pswd="$pswdadmin:" print-response="no">
+ <method>GETNEW</method>
+ <ruri>$calendarpath2:/</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/autopast/suite2/3.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='6' ignore='no'>
+ <description>No items in resource01 Inbox</description>
+ <request user="$useradmin:" pswd="$pswdadmin:" print-response="no">
+ <method>PROPFIND</method>
+ <ruri>$rinboxpath1:/</ruri>
+ <header>
+ <name>Depth</name>
+ <value>1</value>
+ </header>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/PROPFIND/count.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>count</name>
+ <value>0</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='7' ignore='no'>
+ <description>One item in resource01 Calendar</description>
+ <request user="$useradmin:" pswd="$pswdadmin:" print-response="no">
+ <method>GETNEW</method>
+ <ruri>$rcalendarpath1:/</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/autopast/suite2/4.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='8' ignore='no'>
+ <description>Clean-up inboxes</description>
+ <request>
+ <method>DELETEALL</method>
+ <ruri>$inboxpath1:/</ruri>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:">
+ <method>DELETEALL</method>
+ <ruri>$inboxpath2:/</ruri>
+ </request>
+ <request user="$useradmin:" pswd="$pswdadmin:">
+ <method>DELETEALL</method>
+ <ruri>$rinboxpath1:/</ruri>
+ </request>
+ </test>
+ </test-suite>
+
+ <test-suite name='#3 Recurring some in the past' ignore='no'>
+ <test name='1' ignore='no'>
+ <description>Create new event</description>
+ <request>
+ <method>PUT</method>
+ <ruri>$calendarpath1:/3.ics</ruri>
+ <data>
+ <content-type>text/calendar; charset=utf-8</content-type>
+ <filepath>Resource/CalDAV/implicit/autopast/suite3/1.ics</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request>
+ <method>WAITCOUNT 1</method>
+ <ruri>$inboxpath1:/</ruri>
+ </request>
+ </test>
+ <test name='2' ignore='no'>
+ <description>One item in user01 Inbox</description>
+ <request print-response="no">
+ <method>PROPFIND</method>
+ <ruri>$inboxpath1:/</ruri>
+ <header>
+ <name>Depth</name>
+ <value>1</value>
+ </header>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/PROPFIND/count.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>count</name>
+ <value>1</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='3' ignore='no'>
+ <description>One item in user01 Calendar</description>
+ <request print-response="no">
+ <method>GET</method>
+ <ruri>$calendarpath1:/3.ics</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/autopast/suite3/2.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='4' ignore='no'>
+ <description>One item in user02 Inbox</description>
+ <request user="$useradmin:" pswd="$pswdadmin:" print-response="no">
+ <method>PROPFIND</method>
+ <ruri>$inboxpath2:/</ruri>
+ <header>
+ <name>Depth</name>
+ <value>1</value>
+ </header>
+ <data>
+ <content-type>text/calendar; charset=utf-8</content-type>
+ <filepath>Resource/Common/PROPFIND/count.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>count</name>
+ <value>1</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='5' ignore='no'>
+ <description>One item in user02 calendar</description>
+ <request user="$useradmin:" pswd="$pswdadmin:" print-response="no">
+ <method>GETNEW</method>
+ <ruri>$calendarpath2:/</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/autopast/suite3/3.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='6' ignore='no'>
+ <description>No items in resource01 Inbox</description>
+ <request user="$useradmin:" pswd="$pswdadmin:" print-response="no">
+ <method>PROPFIND</method>
+ <ruri>$rinboxpath1:/</ruri>
+ <header>
+ <name>Depth</name>
+ <value>1</value>
+ </header>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/Common/PROPFIND/count.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>count</name>
+ <value>0</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='7' ignore='no'>
+ <description>One item in resource01 Calendar</description>
+ <request user="$useradmin:" pswd="$pswdadmin:" print-response="no">
+ <method>GETNEW</method>
+ <ruri>$rcalendarpath1:/</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/autopast/suite3/4.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='8' ignore='no'>
+ <description>Clean-up inboxes</description>
+ <request>
+ <method>DELETEALL</method>
+ <ruri>$inboxpath1:/</ruri>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:">
+ <method>DELETEALL</method>
+ <ruri>$inboxpath2:/</ruri>
+ </request>
+ <request user="$useradmin:" pswd="$pswdadmin:">
+ <method>DELETEALL</method>
+ <ruri>$rinboxpath1:/</ruri>
+ </request>
+ </test>
+ </test-suite>
+
+ <end>
+ <request>
+ <method>DELETEALL</method>
+ <ruri>$inboxpath1:/</ruri>
+ <ruri>$calendarpath1:/</ruri>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:">
+ <method>DELETEALL</method>
+ <ruri>$inboxpath2:/</ruri>
+ <ruri>$calendarpath2:/</ruri>
+ </request>
+ <request user="$useradmin:" pswd="$pswdadmin:">
+ <method>DELETEALL</method>
+ <ruri>$rinboxpath1:/</ruri>
+ <ruri>$rcalendarpath1:/</ruri>
+ </request>
+ </end>
+
+</caldavtest>
Property changes on: CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CalDAV/implicitoptions.xml
___________________________________________________________________
Modified: svn:mergeinfo
- /CalDAVTester/branches/release/CalDAVTester-3.0-dev/scripts/tests/CalDAV/implicitoptions.xml:7584
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/scripts/tests/implicitoptions.xml:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/scripts/tests/CalDAV/implicitoptions.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/conditional-4466/scripts/tests/implicitoptions.xml:4467-4469
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/scripts/tests/implicitoptions.xml:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/scripts/tests/implicitoptions.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/scripts/tests/CalDAV/implicitoptions.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/scripts/tests/CalDAV/implicitoptions.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/scripts/tests/CalDAV/implicitoptions.xml:5229-5440
/CalDAVTester/trunk/scripts/tests/CalDAV/implicitoptions.xml:10010-10782
+ /CalDAVTester/branches/release/CalDAVTester-3.0-dev/scripts/tests/CalDAV/implicitoptions.xml:7584
/CalDAVTester/branches/users/cdaboo/better-proxy-3148/scripts/tests/implicitoptions.xml:3149-3163
/CalDAVTester/branches/users/cdaboo/component-set-fixes/scripts/tests/CalDAV/implicitoptions.xml:8221-8346
/CalDAVTester/branches/users/cdaboo/conditional-4466/scripts/tests/implicitoptions.xml:4467-4469
/CalDAVTester/branches/users/cdaboo/implicitauto-2948/scripts/tests/implicitoptions.xml:2949-2989
/CalDAVTester/branches/users/cdaboo/normalize-cuaddr-3533/scripts/tests/implicitoptions.xml:3534-3558
/CalDAVTester/branches/users/cdaboo/pycalendar/scripts/tests/CalDAV/implicitoptions.xml:7160-7206
/CalDAVTester/branches/users/cdaboo/pycard/scripts/tests/CalDAV/implicitoptions.xml:7226-7237
/CalDAVTester/branches/users/cdaboo/sharing-5228/scripts/tests/CalDAV/implicitoptions.xml:5229-5440
/CalDAVTester/trunk/scripts/tests/CalDAV/implicitoptions.xml:10010-10865
Modified: CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CalDAV/implicitrecur2.xml
===================================================================
--- CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CalDAV/implicitrecur2.xml 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalDAVTester/branches/users/gaya/sharedgroupstester/scripts/tests/CalDAV/implicitrecur2.xml 2013-03-07 22:42:21 UTC (rev 10867)
@@ -562,6 +562,197 @@
</request>
</test>
</test-suite>
+
+ <test-suite name='Organizer override remove' only='yes'>
+ <test name='1'>
+ <description>Organizer invites Attendee 2 with override</description>
+ <request print-response='no'>
+ <method>PUT</method>
+ <ruri>$calendarpath1:/2.ics</ruri>
+ <data>
+ <content-type>text/calendar; charset=utf-8</content-type>
+ <filepath>Resource/CalDAV/implicit/recur2/override_remove/1.ics</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='2'>
+ <description>Organizer checks data</description>
+ <request print-response='no'>
+ <method>GET</method>
+ <ruri>$calendarpath1:/2.ics</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/recur2/override_remove/2.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='3'>
+ <description>Attendee Inbox Items</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>PROPFIND</method>
+ <ruri>$inboxpath2:/</ruri>
+ <header>
+ <name>Depth</name>
+ <value>1</value>
+ </header>
+ <data>
+ <content-type>text/calendar; charset=utf-8</content-type>
+ <filepath>Resource/Common/PROPFIND/count.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>count</name>
+ <value>1</value>
+ </arg>
+ </verify>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>DELETEALL</method>
+ <ruri>$inboxpath2:/</ruri>
+ </request>
+ </test>
+ <test name='4'>
+ <description>Attendee has data</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>GETNEW</method>
+ <ruri>$calendarpath2:/</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/recur2/override_remove/3.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='5'>
+ <description>Attendee -> Accepted</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>GETNEW</method>
+ <ruri>$calendarpath2:/</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>PUT</method>
+ <ruri>$</ruri>
+ <data>
+ <content-type>text/calendar; charset=utf-8</content-type>
+ <filepath>Resource/CalDAV/implicit/recur2/override_remove/4.ics</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='6'>
+ <description>Organizer Inbox Item</description>
+ <request print-response='no'>
+ <method>WAITCOUNT 1</method>
+ <ruri>$inboxpath1:/</ruri>
+ </request>
+ <request print-response='no'>
+ <method>DELETEALL</method>
+ <ruri>$inboxpath1:/</ruri>
+ </request>
+ </test>
+ <test name='7'>
+ <description>Organizer data changed</description>
+ <request print-response='no'>
+ <method>GET</method>
+ <ruri>$calendarpath1:/2.ics</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/recur2/override_remove/5.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='8'>
+ <description>Organizer removes override</description>
+ <request print-response='no'>
+ <method>PUT</method>
+ <ruri>$calendarpath1:/2.ics</ruri>
+ <data>
+ <content-type>text/calendar; charset=utf-8</content-type>
+ <filepath>Resource/CalDAV/implicit/recur2/override_remove/6.ics</filepath>
+ </data>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ <test name='9'>
+ <description>Organizer checks data</description>
+ <request print-response='no'>
+ <method>GET</method>
+ <ruri>$calendarpath1:/2.ics</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/recur2/override_remove/7.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='10'>
+ <description>Attendee Inbox Items</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>PROPFIND</method>
+ <ruri>$inboxpath2:/</ruri>
+ <header>
+ <name>Depth</name>
+ <value>1</value>
+ </header>
+ <data>
+ <content-type>text/calendar; charset=utf-8</content-type>
+ <filepath>Resource/Common/PROPFIND/count.xml</filepath>
+ </data>
+ <verify>
+ <callback>multistatusItems</callback>
+ <arg>
+ <name>count</name>
+ <value>1</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='11'>
+ <description>Attendee has data</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>GETNEW</method>
+ <ruri>$calendarpath2:/</ruri>
+ <verify>
+ <callback>calendarDataMatch</callback>
+ <arg>
+ <name>filepath</name>
+ <value>Resource/CalDAV/implicit/recur2/override_remove/8.ics</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='12'>
+ <description>Attendee delete Inbox Items</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>DELETEALL</method>
+ <ruri>$inboxpath2:/</ruri>
+ <verify>
+ <callback>statusCode</callback>
+ </verify>
+ </request>
+ </test>
+ </test-suite>
<end>
<request user="$userid1:" pswd="$pswd1:">
Property changes on: CalendarServer/branches/users/gaya/sharedgroups
___________________________________________________________________
Modified: svn:mergeinfo
- /CalendarServer/branches/config-separation:4379-4443
/CalendarServer/branches/egg-info-351:4589-4625
/CalendarServer/branches/generic-sqlstore:6167-6191
/CalendarServer/branches/new-store:5594-5934
/CalendarServer/branches/new-store-no-caldavfile:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2:5936-5981
/CalendarServer/branches/release/CalendarServer-4.3-dev:10180-10190,10192
/CalendarServer/branches/users/cdaboo/batchupload-6699:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692:5693-5702
/CalendarServer/branches/users/cdaboo/component-set-fixes:8130-8346
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627:3628-3644
/CalendarServer/branches/users/cdaboo/implicituidrace:8137-8141
/CalendarServer/branches/users/cdaboo/ischedule-dkim:9747-9979
/CalendarServer/branches/users/cdaboo/managed-attachments:9985-10145
/CalendarServer/branches/users/cdaboo/more-sharing-5591:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464:4465-4957
/CalendarServer/branches/users/cdaboo/pods:7297-7377
/CalendarServer/branches/users/cdaboo/pycalendar:7085-7206
/CalendarServer/branches/users/cdaboo/pycard:7227-7237
/CalendarServer/branches/users/cdaboo/queued-attendee-refreshes:7740-8287
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187:5188-5440
/CalendarServer/branches/users/cdaboo/timezones:7443-7699
/CalendarServer/branches/users/cdaboo/txn-debugging:8730-8743
/CalendarServer/branches/users/glyph/always-abort-txn-on-error:9958-9969
/CalendarServer/branches/users/glyph/case-insensitive-uid:8772-8805
/CalendarServer/branches/users/glyph/conn-limit:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge:4971-5080
/CalendarServer/branches/users/glyph/dalify:6932-7023
/CalendarServer/branches/users/glyph/db-reconnect:6824-6876
/CalendarServer/branches/users/glyph/deploybuild:7563-7572
/CalendarServer/branches/users/glyph/digest-auth-redux:10624-10635
/CalendarServer/branches/users/glyph/disable-quota:7718-7727
/CalendarServer/branches/users/glyph/dont-start-postgres:6592-6614
/CalendarServer/branches/users/glyph/imip-and-admin-html:7866-7984
/CalendarServer/branches/users/glyph/ipv6-client:9054-9105
/CalendarServer/branches/users/glyph/linux-tests:6893-6900
/CalendarServer/branches/users/glyph/migrate-merge:8690-8713
/CalendarServer/branches/users/glyph/misc-portability-fixes:7365-7374
/CalendarServer/branches/users/glyph/more-deferreds-6:6322-6368
/CalendarServer/branches/users/glyph/more-deferreds-7:6369-6445
/CalendarServer/branches/users/glyph/multiget-delete:8321-8330
/CalendarServer/branches/users/glyph/new-export:7444-7485
/CalendarServer/branches/users/glyph/one-home-list-api:10048-10073
/CalendarServer/branches/users/glyph/oracle:7106-7155
/CalendarServer/branches/users/glyph/oracle-nulls:7340-7351
/CalendarServer/branches/users/glyph/other-html:8062-8091
/CalendarServer/branches/users/glyph/parallel-sim:8240-8251
/CalendarServer/branches/users/glyph/parallel-upgrade:8376-8400
/CalendarServer/branches/users/glyph/parallel-upgrade_to_1:8571-8583
/CalendarServer/branches/users/glyph/q:9560-9688
/CalendarServer/branches/users/glyph/queue-locking-and-timing:10204-10289
/CalendarServer/branches/users/glyph/quota:7604-7637
/CalendarServer/branches/users/glyph/sendfdport:5388-5424
/CalendarServer/branches/users/glyph/shared-pool-fixes:8436-8443
/CalendarServer/branches/users/glyph/shared-pool-take2:8155-8174
/CalendarServer/branches/users/glyph/sharedpool:6490-6550
/CalendarServer/branches/users/glyph/sharing-api:9192-9205
/CalendarServer/branches/users/glyph/skip-lonely-vtimezones:8524-8535
/CalendarServer/branches/users/glyph/sql-store:5929-6073
/CalendarServer/branches/users/glyph/subtransactions:7248-7258
/CalendarServer/branches/users/glyph/table-alias:8651-8664
/CalendarServer/branches/users/glyph/uidexport:7673-7676
/CalendarServer/branches/users/glyph/unshare-when-access-revoked:10562-10595
/CalendarServer/branches/users/glyph/use-system-twisted:5084-5149
/CalendarServer/branches/users/glyph/uuid-normalize:9268-9296
/CalendarServer/branches/users/glyph/xattrs-from-files:7757-7769
/CalendarServer/branches/users/sagen/applepush:8126-8184
/CalendarServer/branches/users/sagen/inboxitems:7380-7381
/CalendarServer/branches/users/sagen/locations-resources:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2:5052-5061
/CalendarServer/branches/users/sagen/purge_old_events:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066:4068-4075
/CalendarServer/branches/users/sagen/resources-2:5084-5093
/CalendarServer/branches/users/wsanchez/transations:5515-5593
/CalendarServer/trunk:9885-10758
+ /CalendarServer/branches/config-separation:4379-4443
/CalendarServer/branches/egg-info-351:4589-4625
/CalendarServer/branches/generic-sqlstore:6167-6191
/CalendarServer/branches/new-store:5594-5934
/CalendarServer/branches/new-store-no-caldavfile:5911-5935
/CalendarServer/branches/new-store-no-caldavfile-2:5936-5981
/CalendarServer/branches/release/CalendarServer-4.3-dev:10180-10190,10192
/CalendarServer/branches/users/cdaboo/batchupload-6699:6700-7198
/CalendarServer/branches/users/cdaboo/cached-subscription-calendars-5692:5693-5702
/CalendarServer/branches/users/cdaboo/component-set-fixes:8130-8346
/CalendarServer/branches/users/cdaboo/directory-cache-on-demand-3627:3628-3644
/CalendarServer/branches/users/cdaboo/implicituidrace:8137-8141
/CalendarServer/branches/users/cdaboo/ischedule-dkim:9747-9979
/CalendarServer/branches/users/cdaboo/managed-attachments:9985-10145
/CalendarServer/branches/users/cdaboo/more-sharing-5591:5592-5601
/CalendarServer/branches/users/cdaboo/partition-4464:4465-4957
/CalendarServer/branches/users/cdaboo/pods:7297-7377
/CalendarServer/branches/users/cdaboo/pycalendar:7085-7206
/CalendarServer/branches/users/cdaboo/pycard:7227-7237
/CalendarServer/branches/users/cdaboo/queued-attendee-refreshes:7740-8287
/CalendarServer/branches/users/cdaboo/relative-config-paths-5070:5071-5105
/CalendarServer/branches/users/cdaboo/shared-calendars-5187:5188-5440
/CalendarServer/branches/users/cdaboo/timezones:7443-7699
/CalendarServer/branches/users/cdaboo/txn-debugging:8730-8743
/CalendarServer/branches/users/glyph/always-abort-txn-on-error:9958-9969
/CalendarServer/branches/users/glyph/case-insensitive-uid:8772-8805
/CalendarServer/branches/users/glyph/conn-limit:6574-6577
/CalendarServer/branches/users/glyph/contacts-server-merge:4971-5080
/CalendarServer/branches/users/glyph/dalify:6932-7023
/CalendarServer/branches/users/glyph/db-reconnect:6824-6876
/CalendarServer/branches/users/glyph/deploybuild:7563-7572
/CalendarServer/branches/users/glyph/digest-auth-redux:10624-10635
/CalendarServer/branches/users/glyph/disable-quota:7718-7727
/CalendarServer/branches/users/glyph/dont-start-postgres:6592-6614
/CalendarServer/branches/users/glyph/imip-and-admin-html:7866-7984
/CalendarServer/branches/users/glyph/ipv6-client:9054-9105
/CalendarServer/branches/users/glyph/linux-tests:6893-6900
/CalendarServer/branches/users/glyph/migrate-merge:8690-8713
/CalendarServer/branches/users/glyph/misc-portability-fixes:7365-7374
/CalendarServer/branches/users/glyph/more-deferreds-6:6322-6368
/CalendarServer/branches/users/glyph/more-deferreds-7:6369-6445
/CalendarServer/branches/users/glyph/multiget-delete:8321-8330
/CalendarServer/branches/users/glyph/new-export:7444-7485
/CalendarServer/branches/users/glyph/one-home-list-api:10048-10073
/CalendarServer/branches/users/glyph/oracle:7106-7155
/CalendarServer/branches/users/glyph/oracle-nulls:7340-7351
/CalendarServer/branches/users/glyph/other-html:8062-8091
/CalendarServer/branches/users/glyph/parallel-sim:8240-8251
/CalendarServer/branches/users/glyph/parallel-upgrade:8376-8400
/CalendarServer/branches/users/glyph/parallel-upgrade_to_1:8571-8583
/CalendarServer/branches/users/glyph/q:9560-9688
/CalendarServer/branches/users/glyph/queue-locking-and-timing:10204-10289
/CalendarServer/branches/users/glyph/quota:7604-7637
/CalendarServer/branches/users/glyph/sendfdport:5388-5424
/CalendarServer/branches/users/glyph/shared-pool-fixes:8436-8443
/CalendarServer/branches/users/glyph/shared-pool-take2:8155-8174
/CalendarServer/branches/users/glyph/sharedpool:6490-6550
/CalendarServer/branches/users/glyph/sharing-api:9192-9205
/CalendarServer/branches/users/glyph/skip-lonely-vtimezones:8524-8535
/CalendarServer/branches/users/glyph/sql-store:5929-6073
/CalendarServer/branches/users/glyph/subtransactions:7248-7258
/CalendarServer/branches/users/glyph/table-alias:8651-8664
/CalendarServer/branches/users/glyph/uidexport:7673-7676
/CalendarServer/branches/users/glyph/unshare-when-access-revoked:10562-10595
/CalendarServer/branches/users/glyph/use-system-twisted:5084-5149
/CalendarServer/branches/users/glyph/uuid-normalize:9268-9296
/CalendarServer/branches/users/glyph/xattrs-from-files:7757-7769
/CalendarServer/branches/users/sagen/applepush:8126-8184
/CalendarServer/branches/users/sagen/inboxitems:7380-7381
/CalendarServer/branches/users/sagen/locations-resources:5032-5051
/CalendarServer/branches/users/sagen/locations-resources-2:5052-5061
/CalendarServer/branches/users/sagen/purge_old_events:6735-6746
/CalendarServer/branches/users/sagen/resource-delegates-4038:4040-4067
/CalendarServer/branches/users/sagen/resource-delegates-4066:4068-4075
/CalendarServer/branches/users/sagen/resources-2:5084-5093
/CalendarServer/branches/users/sagen/testing:10827-10851,10853-10855
/CalendarServer/branches/users/wsanchez/transations:5515-5593
/CalendarServer/trunk:9885-10865
Deleted: CalendarServer/branches/users/gaya/sharedgroups/bin/calendarserver_warmup
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/bin/calendarserver_warmup 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/bin/calendarserver_warmup 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,33 +0,0 @@
-#!/usr/bin/env python
-
-##
-# Copyright (c) 2006-2013 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-import sys
-
-#PYTHONPATH
-
-if __name__ == "__main__":
- if "PYTHONPATH" in globals():
- sys.path.insert(0, PYTHONPATH)
- else:
- try:
- import _calendarserver_preamble
- except ImportError:
- sys.exc_clear()
-
- from calendarserver.tools.warmup import main
- main()
Deleted: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/platform/darwin/_sacl.so
===================================================================
(Binary files differ)
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/platform/darwin/od/dsquery.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/platform/darwin/od/dsquery.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/platform/darwin/od/dsquery.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,6 +14,7 @@
# limitations under the License.
#
##
+from __future__ import print_function
"""
Compound query builder. We do this in Python to avoid having to mess
@@ -130,5 +131,5 @@
for expr, result in exprs:
gen = expr.generate()
if gen != result:
- print "Generate expression %s != %s" % (gen, result,)
- print "Done."
+ print("Generate expression %s != %s" % (gen, result,))
+ print("Done.")
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/platform/darwin/od/setup_directory.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/platform/darwin/od/setup_directory.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/platform/darwin/od/setup_directory.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import os
import sys
@@ -204,12 +205,12 @@
def usage(e=None):
name = os.path.basename(sys.argv[0])
- print "usage: %s [options] local_user local_password odmaster_user odmaster_password" % (name,)
- print ""
- print " Configures local and OD master directories for testing"
- print ""
- print "options:"
- print " -h --help: print this help and exit"
+ print("usage: %s [options] local_user local_password odmaster_user odmaster_password" % (name,))
+ print("")
+ print(" Configures local and OD master directories for testing")
+ print("")
+ print("options:")
+ print(" -h --help: print this help and exit")
if e:
sys.exit(1)
else:
@@ -246,7 +247,7 @@
attrs,
None)
if error:
- print error
+ print(error)
raise ODError(error)
return record
@@ -295,7 +296,7 @@
node, error = odframework.ODNode.nodeWithSession_name_error_(session, nodeName, None)
if error:
- print error
+ print(error)
raise ODError(error)
result, error = node.setCredentialsWithRecordType_recordName_password_error_(
@@ -305,45 +306,45 @@
None
)
if error:
- print "Unable to authenticate with directory %s: %s" % (nodeName, error)
+ print("Unable to authenticate with directory %s: %s" % (nodeName, error))
raise ODError(error)
- print "Successfully authenticated with directory %s" % (nodeName,)
+ print("Successfully authenticated with directory %s" % (nodeName,))
- print "Creating users within %s:" % (nodeName,)
+ print("Creating users within %s:" % (nodeName,))
for recordName, attrs in users:
record = lookupRecordName(node, dsattributes.kDSStdRecordTypeUsers, recordName)
if record is None:
- print "Creating user %s" % (recordName,)
+ print("Creating user %s" % (recordName,))
try:
record = createRecord(node, dsattributes.kDSStdRecordTypeUsers, recordName, attrs)
- print "Successfully created user %s" % (recordName,)
+ print("Successfully created user %s" % (recordName,))
result, error = record.changePassword_toPassword_error_(
None, "password", None)
if error or not result:
- print "Failed to set password for %s: %s" % (recordName, error)
+ print("Failed to set password for %s: %s" % (recordName, error))
else:
- print "Successfully set password for %s" % (recordName,)
+ print("Successfully set password for %s" % (recordName,))
except ODError, e:
- print "Failed to create user %s: %s" % (recordName, e)
+ print("Failed to create user %s: %s" % (recordName, e))
else:
- print "User %s already exists" % (recordName,)
+ print("User %s already exists" % (recordName,))
if record is not None:
userRecords.append(record)
- print "Creating groups within %s:" % (nodeName,)
+ print("Creating groups within %s:" % (nodeName,))
for recordName, attrs in groups:
record = lookupRecordName(node, dsattributes.kDSStdRecordTypeGroups, recordName)
if record is None:
- print "Creating group %s" % (recordName,)
+ print("Creating group %s" % (recordName,))
try:
record = createRecord(node, dsattributes.kDSStdRecordTypeGroups, recordName, attrs)
- print "Successfully created group %s" % (recordName,)
+ print("Successfully created group %s" % (recordName,))
except ODError, e:
- print "Failed to create group %s: %s" % (recordName, e)
+ print("Failed to create group %s: %s" % (recordName, e))
else:
- print "Group %s already exists" % (recordName,)
+ print("Group %s already exists" % (recordName,))
print
@@ -359,18 +360,18 @@
for saclGroupName in saclGroupNames:
saclGroupRecord = lookupRecordName(node, dsattributes.kDSStdRecordTypeGroups, saclGroupName)
if saclGroupRecord:
- print "Populating %s SACL group:" % (saclGroupName,)
+ print("Populating %s SACL group:" % (saclGroupName,))
for userRecord in userRecords:
details, error = userRecord.recordDetailsForAttributes_error_(None, None)
recordName = details.get(dsattributes.kDSNAttrRecordName, [None])[0]
result, error = saclGroupRecord.isMemberRecord_error_(userRecord, None)
if result:
- print "%s is already in the %s SACL group" % (recordName, saclGroupName)
+ print("%s is already in the %s SACL group" % (recordName, saclGroupName))
else:
result, error = saclGroupRecord.addMemberRecord_error_(userRecord, None)
- print "Adding %s to the %s SACL group" % (recordName, saclGroupName)
+ print("Adding %s to the %s SACL group" % (recordName, saclGroupName))
- print
+ print("")
class ODError(Exception):
def __init__(self, error):
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/platform/darwin/od/setup_testusers.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/platform/darwin/od/setup_testusers.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/platform/darwin/od/setup_testusers.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import os
import sys
@@ -23,12 +24,12 @@
def usage(e=None):
name = os.path.basename(sys.argv[0])
- print "usage: %s [options] local_user local_password" % (name,)
- print ""
- print " Configures local directory for test users"
- print ""
- print "options:"
- print " -h --help: print this help and exit"
+ print("usage: %s [options] local_user local_password" % (name,))
+ print("")
+ print(" Configures local directory for test users")
+ print("")
+ print("options:")
+ print(" -h --help: print this help and exit")
if e:
sys.exit(1)
else:
@@ -65,7 +66,7 @@
attrs,
None)
if error:
- print error
+ print(error)
raise ODError(error)
return record
@@ -90,7 +91,7 @@
nodeName = "/Local/Default"
node, error = odframework.ODNode.nodeWithSession_name_error_(session, nodeName, None)
if error:
- print error
+ print(error)
raise ODError(error)
result, error = node.setCredentialsWithRecordType_recordName_password_error_(
@@ -100,12 +101,12 @@
None
)
if error:
- print "Unable to authenticate with directory %s: %s" % (nodeName, error)
+ print("Unable to authenticate with directory %s: %s" % (nodeName, error))
raise ODError(error)
- print "Successfully authenticated with directory %s" % (nodeName,)
+ print("Successfully authenticated with directory %s" % (nodeName,))
- print "Creating users within %s:" % (nodeName,)
+ print("Creating users within %s:" % (nodeName,))
for i in xrange(99):
j = i+1
recordName = "user%02d" % (j,)
@@ -120,20 +121,20 @@
record = lookupRecordName(node, dsattributes.kDSStdRecordTypeUsers, recordName)
if record is None:
- print "Creating user %s" % (recordName,)
+ print("Creating user %s" % (recordName,))
try:
record = createRecord(node, dsattributes.kDSStdRecordTypeUsers, recordName, attrs)
- print "Successfully created user %s" % (recordName,)
+ print("Successfully created user %s" % (recordName,))
result, error = record.changePassword_toPassword_error_(
None, password, None)
if error or not result:
- print "Failed to set password for %s: %s" % (recordName, error)
+ print("Failed to set password for %s: %s" % (recordName, error))
else:
- print "Successfully set password for %s" % (recordName,)
+ print("Successfully set password for %s" % (recordName,))
except ODError, e:
- print "Failed to create user %s: %s" % (recordName, e)
+ print("Failed to create user %s: %s" % (recordName, e))
else:
- print "User %s already exists" % (recordName,)
+ print("User %s already exists" % (recordName,))
class ODError(Exception):
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/platform/darwin/od/test/test_opendirectory.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/platform/darwin/od/test/test_opendirectory.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/platform/darwin/od/test/test_opendirectory.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
from twistedcaldav.test.util import TestCase
import hashlib
@@ -41,10 +42,10 @@
if "odtestalbert" in recordNames:
runTests = True
else:
- print "Please run setup_directory.py to populate OD"
+ print("Please run setup_directory.py to populate OD")
except ImportError:
- print "Unable to import OpenDirectory framework"
+ print("Unable to import OpenDirectory framework")
def generateNonce():
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/push/amppush.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/push/amppush.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/push/amppush.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -16,9 +16,8 @@
from calendarserver.push.util import PushScheduler
from twext.python.log import Logger, LoggingMixIn
-from twisted.application.internet import StreamServerEndpointService
from twisted.internet.defer import inlineCallbacks, returnValue
-from twisted.internet.endpoints import TCP4ClientEndpoint, TCP4ServerEndpoint
+from twisted.internet.endpoints import TCP4ClientEndpoint
from twisted.internet.protocol import Factory, ServerFactory
from twisted.protocols import amp
import time
@@ -28,6 +27,10 @@
log = Logger()
+# Control socket message-routing constants
+PUSH_ROUTE = "push"
+
+
# AMP Commands sent to server
class SubscribeToID(amp.Command):
@@ -40,7 +43,7 @@
response = [('status', amp.String())]
-# AMP Commands sent to client
+# AMP Commands sent to client (and forwarded to Master)
class NotificationForID(amp.Command):
arguments = [('id', amp.String()), ('dataChangedTimestamp', amp.Integer())]
@@ -49,29 +52,88 @@
# Server classes
+class AMPPushForwardingFactory(Factory, LoggingMixIn):
-class AMPPushNotifierService(StreamServerEndpointService, LoggingMixIn):
+ def __init__(self, forwarder):
+ self.forwarder = forwarder
+
+ def buildProtocol(self, addr):
+ protocol = amp.AMP()
+ self.forwarder.protocols.append(protocol)
+ return protocol
+
+class AMPPushForwarder(LoggingMixIn):
"""
+ Runs in the slaves, forwards notifications to the master via AMP
+ """
+ def __init__(self, controlSocket):
+ self.protocols = []
+ controlSocket.addFactory(PUSH_ROUTE, AMPPushForwardingFactory(self))
+
+ @inlineCallbacks
+ def enqueue(self, id, dataChangedTimestamp=None):
+ if dataChangedTimestamp is None:
+ dataChangedTimestamp = int(time.time())
+ for protocol in self.protocols:
+ yield protocol.callRemote(NotificationForID, id=id,
+ dataChangedTimestamp=dataChangedTimestamp)
+
+
+
+class AMPPushMasterListeningProtocol(amp.AMP, LoggingMixIn):
+ """
+ Listens for notifications coming in over AMP from the slaves
+ """
+ def __init__(self, master):
+ super(AMPPushMasterListeningProtocol, self).__init__()
+ self.master = master
+
+ @NotificationForID.responder
+ def enqueueFromWorker(self, id, dataChangedTimestamp=None):
+ if dataChangedTimestamp is None:
+ dataChangedTimestamp = int(time.time())
+ self.master.enqueue(id, dataChangedTimestamp=dataChangedTimestamp)
+ return {"status" : "OK"}
+
+
+class AMPPushMasterListenerFactory(Factory, LoggingMixIn):
+
+ def __init__(self, master):
+ self.master = master
+
+ def buildProtocol(self, addr):
+ protocol = AMPPushMasterListeningProtocol(self.master)
+ return protocol
+
+
+class AMPPushMaster(LoggingMixIn):
+ """
AMPPushNotifierService allows clients to use AMP to subscribe to,
and receive, change notifications.
"""
- @classmethod
- def makeService(cls, settings, ignored, reactor=None):
- return cls(settings, reactor=reactor)
-
- def __init__(self, settings, reactor=None):
+ def __init__(self, controlSocket, parentService, port, enableStaggering,
+ staggerSeconds, reactor=None):
if reactor is None:
from twisted.internet import reactor
- factory = AMPPushNotifierFactory(self)
- endpoint = TCP4ServerEndpoint(reactor, settings["Port"])
- super(AMPPushNotifierService, self).__init__(endpoint, factory)
+ from twisted.application.strports import service as strPortsService
+
+ if port:
+ # Service which listens for client subscriptions and sends
+ # notifications to them
+ strPortsService(str(port), AMPPushNotifierFactory(self),
+ reactor=reactor).setServiceParent(parentService)
+
+ if controlSocket is not None:
+ # Set up the listener which gets notifications from the slaves
+ controlSocket.addFactory(PUSH_ROUTE,
+ AMPPushMasterListenerFactory(self))
+
self.subscribers = []
- self.dataHost = settings["DataHost"]
- if settings["EnableStaggering"]:
+ if enableStaggering:
self.scheduler = PushScheduler(reactor, self.sendNotification,
- staggerSeconds=settings["StaggerSeconds"])
+ staggerSeconds=staggerSeconds)
else:
self.scheduler = None
@@ -83,45 +145,32 @@
self.log_debug("Removed subscriber")
self.subscribers.remove(p)
- def enqueue(self, id, dataChangedTimestamp=None):
+ def enqueue(self, pushKey, dataChangedTimestamp=None):
"""
- Sends an AMP push notification to any clients subscribing to this id.
+ Sends an AMP push notification to any clients subscribing to this pushKey.
- @param id: The identifier of the resource that was updated, including
+ @param pushKey: The identifier of the resource that was updated, including
a prefix indicating whether this is CalDAV or CardDAV related.
- The prefix is separated from the id with "|", e.g.:
- "CalDAV|abc/def"
+ "/CalDAV/abc/def/"
- The id is an opaque token as far as this code is concerned, and
- is used in conjunction with the prefix and the server hostname
- to build the actual key value that devices subscribe to.
- @type id: C{str}
+ @type pushKey: C{str}
@param dataChangedTimestamp: Timestamp (epoch seconds) for the data change
which triggered this notification (Only used for unit tests)
@type key: C{int}
"""
- try:
- protocol, id = id.split("|", 1)
- except ValueError:
- # id has no protocol, so we can't do anything with it
- self.log_error("Notification id '%s' is missing protocol" % (id,))
- return
-
# Unit tests can pass this value in; otherwise it defaults to now
if dataChangedTimestamp is None:
dataChangedTimestamp = int(time.time())
- id = "/%s/%s/%s/" % (protocol, self.dataHost, id)
-
tokens = []
for subscriber in self.subscribers:
- token = subscriber.subscribedToID(id)
+ token = subscriber.subscribedToID(pushKey)
if token is not None:
tokens.append(token)
if tokens:
- return self.scheduleNotifications(tokens, id, dataChangedTimestamp)
+ return self.scheduleNotifications(tokens, pushKey, dataChangedTimestamp)
@inlineCallbacks
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/push/applepush.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/push/applepush.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/push/applepush.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -88,7 +88,6 @@
service.store = store
service.providers = {}
service.feedbacks = {}
- service.dataHost = settings["DataHost"]
service.purgeCall = None
service.purgeIntervalSeconds = settings["SubscriptionPurgeIntervalSeconds"]
service.purgeSeconds = settings["SubscriptionPurgeSeconds"]
@@ -177,31 +176,27 @@
@inlineCallbacks
- def enqueue(self, id, dataChangedTimestamp=None):
+ def enqueue(self, pushKey, dataChangedTimestamp=None):
"""
Sends an Apple Push Notification to any device token subscribed to
- this id.
+ this pushKey.
- @param id: The identifier of the resource that was updated, including
+ @param pushKey: The identifier of the resource that was updated, including
a prefix indicating whether this is CalDAV or CardDAV related.
- The prefix is separated from the id with "|", e.g.:
- "CalDAV|abc/def"
+ "/CalDAV/abc/def/"
- The id is an opaque token as far as this code is concerned, and
- is used in conjunction with the prefix and the server hostname
- to build the actual key value that devices subscribe to.
- @type id: C{str}
+ @type pushKey: C{str}
@param dataChangedTimestamp: Timestamp (epoch seconds) for the data change
which triggered this notification (Only used for unit tests)
@type key: C{int}
"""
try:
- protocol, id = id.split("|", 1)
+ protocol = pushKey.split("/")[1]
except ValueError:
- # id has no protocol, so we can't do anything with it
- self.log_error("Notification id '%s' is missing protocol" % (id,))
+ # pushKey has no protocol, so we can't do anything with it
+ self.log_error("Push key '%s' is missing protocol" % (pushKey,))
return
# Unit tests can pass this value in; otherwise it defaults to now
@@ -210,23 +205,22 @@
provider = self.providers.get(protocol, None)
if provider is not None:
- key = "/%s/%s/%s/" % (protocol, self.dataHost, id)
# Look up subscriptions for this key
txn = self.store.newTransaction()
- subscriptions = (yield txn.apnSubscriptionsByKey(key))
+ subscriptions = (yield txn.apnSubscriptionsByKey(pushKey))
yield txn.commit()
numSubscriptions = len(subscriptions)
if numSubscriptions > 0:
self.log_debug("Sending %d APNS notifications for %s" %
- (numSubscriptions, key))
+ (numSubscriptions, pushKey))
tokens = []
for token, uid in subscriptions:
if token and uid:
tokens.append(token)
if tokens:
- provider.scheduleNotifications(tokens, key, dataChangedTimestamp)
+ provider.scheduleNotifications(tokens, pushKey, dataChangedTimestamp)
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/push/test/test_amppush.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/push/test/test_amppush.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/push/test/test_amppush.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,30 +14,18 @@
# limitations under the License.
##
-from calendarserver.push.amppush import AMPPushNotifierService, AMPPushNotifierProtocol
+from calendarserver.push.amppush import AMPPushMaster, AMPPushNotifierProtocol
from calendarserver.push.amppush import NotificationForID
from twistedcaldav.test.util import TestCase
-from twisted.internet.defer import inlineCallbacks
from twisted.internet.task import Clock
-class AMPPushNotifierServiceTests(TestCase):
+class AMPPushMasterTests(TestCase):
- @inlineCallbacks
- def test_AMPPushNotifierService(self):
+ def test_AMPPushMaster(self):
- settings = {
- "Service" : "calendarserver.push.amppush.AMPPushNotifierService",
- "Enabled" : True,
- "Port" : 62311,
- "EnableStaggering" : True,
- "StaggerSeconds" : 3,
- "DataHost" : "localhost",
- }
-
# Set up the service
clock = Clock()
- service = (yield AMPPushNotifierService.makeService(settings,
- None, reactor=clock))
+ service = AMPPushMaster(None, None, 0, True, 3, reactor=clock)
self.assertEquals(service.subscribers, [])
@@ -69,7 +57,7 @@
self.assertTrue(client3.subscribedToID("/CalDAV/localhost/user03/"))
dataChangedTimestamp = 1354815999
- service.enqueue("CalDAV|user01", dataChangedTimestamp=dataChangedTimestamp)
+ service.enqueue("/CalDAV/localhost/user01/", dataChangedTimestamp=dataChangedTimestamp)
self.assertEquals(len(client1.history), 0)
self.assertEquals(len(client2.history), 0)
self.assertEquals(len(client3.history), 0)
@@ -86,7 +74,7 @@
client1.reset()
client2.reset()
client2.unsubscribe("token2", "/CalDAV/localhost/user01/")
- service.enqueue("CalDAV|user01", dataChangedTimestamp=dataChangedTimestamp)
+ service.enqueue("/CalDAV/localhost/user01/", dataChangedTimestamp=dataChangedTimestamp)
self.assertEquals(len(client1.history), 0)
clock.advance(1)
self.assertEquals(client1.history, [(NotificationForID, {'id': '/CalDAV/localhost/user01/', 'dataChangedTimestamp' : 1354815999})])
@@ -99,7 +87,7 @@
client1.reset()
client2.reset()
client2.subscribe("token2", "/CalDAV/localhost/user01/")
- service.enqueue("CalDAV|user01", dataChangedTimestamp=dataChangedTimestamp)
+ service.enqueue("/CalDAV/localhost/user01/", dataChangedTimestamp=dataChangedTimestamp)
self.assertEquals(client1.history, [(NotificationForID, {'id': '/CalDAV/localhost/user01/', 'dataChangedTimestamp' : 1354815999})])
self.assertEquals(client2.history, [(NotificationForID, {'id': '/CalDAV/localhost/user01/', 'dataChangedTimestamp' : 1354815999})])
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/push/test/test_applepush.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/push/test/test_applepush.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/push/test/test_applepush.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -38,12 +38,10 @@
def test_ApplePushNotifierService(self):
settings = {
- "Service" : "calendarserver.push.applepush.ApplePushNotifierService",
"Enabled" : True,
"SubscriptionURL" : "apn",
"SubscriptionPurgeSeconds" : 24 * 60 * 60,
"SubscriptionPurgeIntervalSeconds" : 24 * 60 * 60,
- "DataHost" : "calendars.example.com",
"ProviderHost" : "gateway.push.apple.com",
"ProviderPort" : 2195,
"FeedbackHost" : "feedback.push.apple.com",
@@ -127,7 +125,7 @@
# Notification arrives from calendar server
dataChangedTimestamp = 1354815999
- yield service.enqueue("CalDAV|user01/calendar",
+ yield service.enqueue("/CalDAV/calendars.example.com/user01/calendar/",
dataChangedTimestamp=dataChangedTimestamp)
# The notifications should be in the queue
@@ -167,7 +165,7 @@
# Reset sent data
providerConnector.transport.data = None
# Send notification while service is connected
- yield service.enqueue("CalDAV|user01/calendar")
+ yield service.enqueue("/CalDAV/calendars.example.com/user01/calendar/")
clock.advance(1) # so that first push is sent
self.assertEquals(len(providerConnector.transport.data), 183)
# Reset sent data
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/push/test/test_notifier.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/push/test/test_notifier.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/push/test/test_notifier.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,15 +15,16 @@
##
from twistedcaldav.test.util import TestCase
+from calendarserver.push.notifier import PushDistributor
+from calendarserver.push.notifier import getPubSubAPSConfiguration
+from calendarserver.push.notifier import PushNotificationWork
+from twisted.internet.defer import inlineCallbacks, succeed
from twistedcaldav.config import ConfigDict
-from calendarserver.push.notifier import PushService
-from twisted.internet.defer import inlineCallbacks, succeed
-from twisted.application import service
+from txdav.common.datastore.test.util import buildStore
-class StubService(service.Service):
- def __init__(self, settings, store):
- self.settings = settings
- self.store = store
+
+class StubService(object):
+ def __init__(self):
self.reset()
def reset(self):
@@ -33,25 +34,89 @@
self.history.append(id)
return(succeed(None))
- @classmethod
- def makeService(cls, settings, store):
- return cls(settings, store)
+class PushDistributorTests(TestCase):
-class PushServiceTests(TestCase):
-
@inlineCallbacks
def test_enqueue(self):
- settings = ConfigDict({
- "Services" : {
- "Stub" : {
- "Service" : "calendarserver.push.test.test_notifier.StubService",
- "Enabled" : True,
- "Foo" : "Bar",
+ stub = StubService()
+ dist = PushDistributor([stub])
+ yield dist.enqueue("testing")
+ self.assertEquals(stub.history, ["testing"])
+
+ def test_getPubSubAPSConfiguration(self):
+ config = ConfigDict({
+ "EnableSSL" : True,
+ "ServerHostName" : "calendars.example.com",
+ "SSLPort" : 8443,
+ "HTTPPort" : 8008,
+ "Notifications" : {
+ "Services" : {
+ "APNS" : {
+ "CalDAV" : {
+ "Topic" : "test topic",
+ },
+ "SubscriptionRefreshIntervalSeconds" : 42,
+ "SubscriptionURL" : "apns",
+ "Environment" : "prod",
+ "Enabled" : True,
+ },
},
},
})
- svc = PushService.makeService(settings, None)
- yield svc.enqueue("testing")
- self.assertEquals(svc.subServices[0].history, ["testing"])
+ result = getPubSubAPSConfiguration("CalDAV|foo", config)
+ self.assertEquals(
+ result,
+ {
+ "SubscriptionRefreshIntervalSeconds": 42,
+ "SubscriptionURL": "https://calendars.example.com:8443/apns",
+ "APSBundleID": "test topic",
+ "APSEnvironment": "prod"
+ }
+ )
+class StubDistributor(object):
+ def __init__(self):
+ self.reset()
+
+ def reset(self):
+ self.history = []
+
+ def enqueue(self, pushID):
+ self.history.append(pushID)
+
+class PushNotificationWorkTests(TestCase):
+
+ @inlineCallbacks
+ def test_work(self):
+ self.store = yield buildStore(self, None)
+
+ pushDistributor = StubDistributor()
+
+ def decorateTransaction(txn):
+ txn._pushDistributor = pushDistributor
+
+ self.store.callWithNewTransactions(decorateTransaction)
+
+ txn = self.store.newTransaction()
+ wp = (yield txn.enqueue(PushNotificationWork,
+ pushID="/CalDAV/localhost/foo/",
+ ))
+ yield txn.commit()
+ yield wp.whenExecuted()
+ self.assertEquals(pushDistributor.history, ["/CalDAV/localhost/foo/"])
+
+ pushDistributor.reset()
+ txn = self.store.newTransaction()
+ wp = (yield txn.enqueue(PushNotificationWork,
+ pushID="/CalDAV/localhost/bar/",
+ ))
+ wp = (yield txn.enqueue(PushNotificationWork,
+ pushID="/CalDAV/localhost/bar/",
+ ))
+ wp = (yield txn.enqueue(PushNotificationWork,
+ pushID="/CalDAV/localhost/bar/",
+ ))
+ yield txn.commit()
+ yield wp.whenExecuted()
+ self.assertEquals(pushDistributor.history, ["/CalDAV/localhost/bar/"])
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tap/caldav.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tap/caldav.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tap/caldav.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
__all__ = [
"CalDAVService",
@@ -105,7 +106,9 @@
from calendarserver.tap.util import oracleConnectorFromConfig
from calendarserver.tap.cfgchild import ConfiguredChildSpawner
from calendarserver.tools.util import checkDirectory
-from calendarserver.push.notifier import PushService
+from calendarserver.push.notifier import PushDistributor
+from calendarserver.push.amppush import AMPPushMaster, AMPPushForwarder
+from calendarserver.push.applepush import ApplePushNotifierService
from twistedcaldav.scheduling.imip.inbound import MailRetriever
try:
@@ -366,7 +369,7 @@
self.loadConfiguration()
self.checkConfiguration()
except ConfigurationError, e:
- print "Invalid configuration: %s" % (e,)
+ print("Invalid configuration: %s" % (e,))
sys.exit(1)
@@ -375,7 +378,7 @@
raise ConfigurationError("Config file %s not found. Exiting."
% (self["config"],))
- print "Reading configuration from file: %s" % (self["config"],)
+ print("Reading configuration from file: %s" % (self["config"],))
config.load(self["config"])
config.updateDefaults(self.overrides)
@@ -390,7 +393,7 @@
# Having CalDAV *and* CardDAV both disabled is an illegal configuration
# for a running server (but is fine for command-line utilities)
if not config.EnableCalDAV and not config.EnableCardDAV:
- print "Neither EnableCalDAV nor EnableCardDAV are set to True."
+ print("Neither EnableCalDAV nor EnableCardDAV are set to True.")
sys.exit(1)
uid, gid = None, None
@@ -539,7 +542,6 @@
)
self.monitor.addProcessObject(process, PARENT_ENVIRONMENT)
-
if config.GroupCaching.Enabled and config.GroupCaching.EnableUpdater:
self.maker.log_info("Adding group caching service")
@@ -710,18 +712,56 @@
"""
pool, txnFactory = getDBPool(config)
store = storeFromConfig(config, txnFactory)
- result = self.requestProcessingService(options, store)
+ logObserver = AMPCommonAccessLoggingObserver()
+ result = self.requestProcessingService(options, store, logObserver)
directory = result.rootResource.getDirectory()
if pool is not None:
pool.setServiceParent(result)
+ if config.ControlSocket:
+ id = config.ControlSocket
+ self.log_info("Control via AF_UNIX: %s" % (id,))
+ endpointFactory = lambda reactor: UNIXClientEndpoint(
+ reactor, id)
+ else:
+ id = int(config.ControlPort)
+ self.log_info("Control via AF_INET: %d" % (id,))
+ endpointFactory = lambda reactor: TCP4ClientEndpoint(
+ reactor, "127.0.0.1", id)
+ controlSocketClient = ControlSocket()
+ class LogClient(AMP):
+ def startReceivingBoxes(self, sender):
+ super(LogClient, self).startReceivingBoxes(sender)
+ logObserver.addClient(self)
+ f = Factory()
+ f.protocol = LogClient
+ controlSocketClient.addFactory(_LOG_ROUTE, f)
+ from txdav.common.datastore.sql import CommonDataStore as SQLStore
+ if isinstance(store, SQLStore):
+ def queueMasterAvailable(connectionFromMaster):
+ store.queuer = store.queuer.transferProposalCallbacks(connectionFromMaster)
+ queueFactory = QueueWorkerFactory(store.newTransaction, schema,
+ queueMasterAvailable)
+ controlSocketClient.addFactory(_QUEUE_ROUTE, queueFactory)
+ controlClient = ControlSocketConnectingService(
+ endpointFactory, controlSocketClient
+ )
+ controlClient.setServiceParent(result)
# Optionally set up push notifications
+ pushDistributor = None
if config.Notifications.Enabled:
- pushService = PushService.makeService(config.Notifications, store)
- pushService.setServiceParent(result)
- else:
- pushService = None
+ observers = []
+ if config.Notifications.Services.APNS.Enabled:
+ pushSubService = ApplePushNotifierService.makeService(
+ config.Notifications.Services.APNS, store)
+ observers.append(pushSubService)
+ pushSubService.setServiceParent(result)
+ if config.Notifications.Services.AMP.Enabled:
+ pushSubService = AMPPushForwarder(controlSocketClient)
+ observers.append(pushSubService)
+ if observers:
+ pushDistributor = PushDistributor(observers)
# Optionally set up mail retrieval
if config.Scheduling.iMIP.Enabled:
@@ -732,7 +772,7 @@
mailRetriever = None
def decorateTransaction(txn):
- txn._pushService = pushService
+ txn._pushDistributor = pushDistributor
txn._rootResource = result.rootResource
txn._mailRetriever = mailRetriever
@@ -755,15 +795,15 @@
"passwd" : config.Manhole.PasswordFilePath,
})
manholeService.setServiceParent(result)
- # Using print because logging isn't ready at this point
- print "Manhole access enabled: %s" % (portString,)
+ # Using print(because logging isn't ready at this point)
+ print("Manhole access enabled: %s" % (portString,))
except ImportError:
- print "Manhole access could not enabled because manhole_tap could not be imported"
+ print("Manhole access could not enabled because manhole_tap could not be imported")
return result
- def requestProcessingService(self, options, store):
+ def requestProcessingService(self, options, store, logObserver):
"""
Make a service that will actually process HTTP requests.
@@ -787,52 +827,8 @@
#
self.log_info("Setting up service")
- bonusServices = []
-
- if config.ProcessType == "Slave":
- logObserver = AMPCommonAccessLoggingObserver()
-
- if config.ControlSocket:
- id = config.ControlSocket
- self.log_info("Control via AF_UNIX: %s" % (id,))
- endpointFactory = lambda reactor: UNIXClientEndpoint(
- reactor, id)
- else:
- id = int(config.ControlPort)
- self.log_info("Control via AF_INET: %d" % (id,))
- endpointFactory = lambda reactor: TCP4ClientEndpoint(
- reactor, "127.0.0.1", id)
- controlSocketClient = ControlSocket()
- class LogClient(AMP):
- def startReceivingBoxes(self, sender):
- super(LogClient, self).startReceivingBoxes(sender)
- logObserver.addClient(self)
- f = Factory()
- f.protocol = LogClient
- controlSocketClient.addFactory(_LOG_ROUTE, f)
- from txdav.common.datastore.sql import CommonDataStore as SQLStore
- if isinstance(store, SQLStore):
- def queueMasterAvailable(connectionFromMaster):
- store.queuer = store.queuer.transferProposalCallbacks(connectionFromMaster)
- queueFactory = QueueWorkerFactory(store.newTransaction, schema,
- queueMasterAvailable)
- controlSocketClient.addFactory(_QUEUE_ROUTE, queueFactory)
- controlClient = ControlSocketConnectingService(
- endpointFactory, controlSocketClient
- )
- bonusServices.append(controlClient)
- elif config.ProcessType == "Single":
- # Make sure no old socket files are lying around.
- self.deleteStaleSocketFiles()
- logObserver = RotatingFileAccessLoggingObserver(
- config.AccessLogFile,
- )
-
self.log_info("Configuring access log observer: %s" % (logObserver,))
-
service = CalDAVService(logObserver)
- for bonus in bonusServices:
- bonus.setServiceParent(service)
rootResource = getRootResource(config, store, additional)
service.rootResource = rootResource
@@ -1019,13 +1015,57 @@
Create a service to be used in a single-process, stand-alone
configuration.
"""
- def slaveSvcCreator(pool, store):
- return self.requestProcessingService(options, store)
+ def slaveSvcCreator(pool, store, logObserver):
+ result = self.requestProcessingService(options, store, logObserver)
+ # Optionally set up push notifications
+ pushDistributor = None
+ if config.Notifications.Enabled:
+ observers = []
+ if config.Notifications.Services.APNS.Enabled:
+ pushSubService = ApplePushNotifierService.makeService(
+ config.Notifications.Services.APNS, store)
+ observers.append(pushSubService)
+ pushSubService.setServiceParent(result)
+ if config.Notifications.Services.AMP.Enabled:
+ pushSubService = AMPPushMaster(None, result,
+ config.Notifications.Services.AMP.Port,
+ config.Notifications.Services.AMP.EnableStaggering,
+ config.Notifications.Services.AMP.StaggerSeconds
+ )
+ observers.append(pushSubService)
+ if observers:
+ pushDistributor = PushDistributor(observers)
+
+ # Optionally set up mail retrieval
+ if config.Scheduling.iMIP.Enabled:
+ directory = result.rootResource.getDirectory()
+ mailRetriever = MailRetriever(store, directory,
+ config.Scheduling.iMIP.Receiving)
+ mailRetriever.setServiceParent(result)
+ else:
+ mailRetriever = None
+
+ def decorateTransaction(txn):
+ txn._pushDistributor = pushDistributor
+ txn._rootResource = result.rootResource
+ txn._mailRetriever = mailRetriever
+
+ store.callWithNewTransactions(decorateTransaction)
+
+ return result
+
uid, gid = getSystemIDs(config.UserName, config.GroupName)
- return self.storageService(slaveSvcCreator, uid=uid, gid=gid)
+ # Make sure no old socket files are lying around.
+ self.deleteStaleSocketFiles()
+ logObserver = RotatingFileAccessLoggingObserver(
+ config.AccessLogFile,
+ )
+ return self.storageService(slaveSvcCreator, logObserver, uid=uid, gid=gid)
+
+
def makeService_Utility(self, options):
"""
Create a service to be used in a command-line utility
@@ -1034,14 +1074,14 @@
When created, that service will have access to the storage facilities.
"""
- def toolServiceCreator(pool, store):
+ def toolServiceCreator(pool, store, ignored):
return config.UtilityServiceClass(store)
uid, gid = getSystemIDs(config.UserName, config.GroupName)
- return self.storageService(toolServiceCreator, uid=uid, gid=gid)
+ return self.storageService(toolServiceCreator, None, uid=uid, gid=gid)
- def storageService(self, createMainService, uid=None, gid=None):
+ def storageService(self, createMainService, logObserver, uid=None, gid=None):
"""
If necessary, create a service to be started used for storage; for
example, starting a database backend. This service will then start the
@@ -1080,7 +1120,7 @@
maxConnections=config.MaxDBConnectionsPerPool)
cp.setServiceParent(ms)
store = storeFromConfig(config, cp.connection)
- mainService = createMainService(cp, store)
+ mainService = createMainService(cp, store, logObserver)
if config.SharedConnectionPool:
dispenser = ConnectionDispenser(cp)
else:
@@ -1111,6 +1151,7 @@
store, uid=overrideUID, gid=overrideGID,
),
store, uid=overrideUID, gid=overrideGID,
+ failIfUpgradeNeeded=config.FailIfUpgradeNeeded,
)
)
upgradeSvc.setServiceParent(ms)
@@ -1153,7 +1194,7 @@
raise UsageError("Unknown database type %r" (config.DBType,))
else:
store = storeFromConfig(config, None)
- return createMainService(None, store)
+ return createMainService(None, store, logObserver)
def makeService_Combined(self, options):
@@ -1196,6 +1237,17 @@
controlSocket = ControlSocket()
controlSocket.addFactory(_LOG_ROUTE, logger)
+
+ # Optionally set up AMPPushMaster
+ if config.Notifications.Enabled and config.Notifications.Services.AMP.Enabled:
+ ampSettings = config.Notifications.Services.AMP
+ AMPPushMaster(
+ controlSocket,
+ s,
+ ampSettings["Port"],
+ ampSettings["EnableStaggering"],
+ ampSettings["StaggerSeconds"]
+ )
if config.ControlSocket:
controlSocketService = GroupOwnedUNIXServer(
gid, config.ControlSocket, controlSocket, mode=0660
@@ -1324,10 +1376,10 @@
"passwd" : config.Manhole.PasswordFilePath,
})
manholeService.setServiceParent(s)
- # Using print because logging isn't ready at this point
- print "Manhole access enabled: %s" % (portString,)
+ # Using print(because logging isn't ready at this point)
+ print("Manhole access enabled: %s" % (portString,))
except ImportError:
- print "Manhole access could not enabled because manhole_tap could not be imported"
+ print("Manhole access could not enabled because manhole_tap could not be imported")
# Finally, let's get the real show on the road. Create a service that
@@ -1338,7 +1390,7 @@
# to), and second, the service which does an upgrade from the
# filesystem to the database (if that's necessary, and there is
# filesystem data in need of upgrading).
- def spawnerSvcCreator(pool, store):
+ def spawnerSvcCreator(pool, store, ignored):
from twisted.internet import reactor
pool = PeerConnectionPool(reactor, store.newTransaction,
7654, schema)
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tap/util.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tap/util.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tap/util.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -225,7 +225,8 @@
if config.Notifications.Enabled:
# FIXME: NotifierFactory needs reference to the store in order
# to get a txn in order to create a Work item
- notifierFactory = NotifierFactory(None, config.ServerHostName)
+ notifierFactory = NotifierFactory(None, config.ServerHostName,
+ config.Notifications.CoalesceSeconds)
else:
notifierFactory = None
quota = config.UserQuota
@@ -654,7 +655,7 @@
#
# Apple Push Notification Subscriptions
#
- apnConfig = config.Notifications.Services["ApplePushNotifier"]
+ apnConfig = config.Notifications.Services.APNS
if apnConfig.Enabled:
log.info("Setting up APNS resource at /%s" %
(apnConfig["SubscriptionURL"],))
Property changes on: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools
___________________________________________________________________
Modified: svn:ignore
- *.pyc
+ *.pyc
config.py.edited
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/ampnotifications.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/ampnotifications.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/ampnotifications.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
from calendarserver.push.amppush import subscribeToIDs
from calendarserver.tools.cmdline import utilityMain
@@ -34,17 +35,17 @@
def usage(e=None):
name = os.path.basename(sys.argv[0])
- print "usage: %s [options] [pushkey ...]" % (name,)
- print ""
- print " Monitor AMP Push Notifications"
- print ""
- print "options:"
- print " -h --help: print this help and exit"
- print " -f --config <path>: Specify caldavd.plist configuration path"
- print " -p --port <port>: AMP port to connect to"
- print " -s --server <hostname>: AMP server to connect to"
- print " --debug: verbose logging"
- print ""
+ print("usage: %s [options] [pushkey ...]" % (name,))
+ print("")
+ print(" Monitor AMP Push Notifications")
+ print("")
+ print("options:")
+ print(" -h --help: print this help and exit")
+ print(" -f --config <path>: Specify caldavd.plist configuration path")
+ print(" -p --port <port>: AMP port to connect to")
+ print(" -s --server <hostname>: AMP server to connect to")
+ print(" --debug: verbose logging")
+ print("")
if e:
sys.stderr.write("%s\n" % (e,))
@@ -141,13 +142,13 @@
def notificationCallback(id, dataChangedTimestamp):
- print "Received notification for:", id
+ print("Received notification for:", id)
return succeed(True)
@inlineCallbacks
def monitorAMPNotifications(hostname, port, ids):
- print "Subscribing to notifications..."
+ print("Subscribing to notifications...")
yield subscribeToIDs(hostname, port, ids, notificationCallback)
- print "Waiting for notifications..."
+ print("Waiting for notifications...")
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/anonymize.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/anonymize.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/anonymize.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,7 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
-
+from __future__ import print_function
from __future__ import with_statement
from getopt import getopt, GetoptError
@@ -47,20 +47,20 @@
def usage(e=None):
if e:
- print e
- print ""
+ print(e)
+ print("")
name = os.path.basename(sys.argv[0])
- print "usage: %s [options] source destination" % (name,)
- print ""
- print " Anonymizes calendar data"
- print ""
- print " source and destination should refer to document root directories"
- print ""
- print "options:"
- print " -h --help: print this help and exit"
- print " -n --node <node>: Directory node (defaults to /Search)"
- print ""
+ print("usage: %s [options] source destination" % (name,))
+ print("")
+ print(" Anonymizes calendar data")
+ print("")
+ print(" source and destination should refer to document root directories")
+ print("")
+ print("options:")
+ print(" -h --help: print this help and exit")
+ print(" -n --node <node>: Directory node (defaults to /Search)")
+ print("")
if e:
sys.exit(64)
@@ -110,14 +110,14 @@
def anonymizeRoot(directoryMap, sourceDirectory, destDirectory):
# sourceDirectory and destDirectory are DocumentRoots
- print "Anonymizing calendar data from %s into %s" % (sourceDirectory, destDirectory)
+ print("Anonymizing calendar data from %s into %s" % (sourceDirectory, destDirectory))
homes = 0
calendars = 0
resources = 0
if not os.path.exists(sourceDirectory):
- print "Can't find source: %s" % (sourceDirectory,)
+ print("Can't find source: %s" % (sourceDirectory,))
sys.exit(1)
if not os.path.exists(destDirectory):
@@ -147,7 +147,7 @@
for home in os.listdir(secondPath):
record = directoryMap.lookupCUA(home)
if not record:
- print "Couldn't find %s, skipping." % (home,)
+ print("Couldn't find %s, skipping." % (home,))
continue
sourceHome = os.path.join(secondPath, home)
destHome = os.path.join(destUidHomes,
@@ -162,13 +162,13 @@
continue
record = directoryMap.lookupCUA(home)
if not record:
- print "Couldn't find %s, skipping." % (home,)
+ print("Couldn't find %s, skipping." % (home,))
continue
sourceHome = os.path.join(sourceUidHomes, home)
destHome = os.path.join(destUidHomes, record['guid'])
homeList.append((sourceHome, destHome, record))
- print "Processing %d calendar homes..." % (len(homeList),)
+ print("Processing %d calendar homes..." % (len(homeList),))
for sourceHome, destHome, record in homeList:
quotaUsed = 0
@@ -268,23 +268,23 @@
)
if not (homes % 100):
- print " %d..." % (homes,)
+ print(" %d..." % (homes,))
- print "Done."
- print ""
+ print("Done.")
+ print("")
- print "Calendar totals:"
- print " Calendar homes: %d" % (homes,)
- print " Calendars: %d" % (calendars,)
- print " Events: %d" % (resources,)
- print ""
+ print("Calendar totals:")
+ print(" Calendar homes: %d" % (homes,))
+ print(" Calendars: %d" % (calendars,))
+ print(" Events: %d" % (resources,))
+ print("")
def anonymizeData(directoryMap, data):
try:
pyobj = PyCalendar.parseText(data)
except Exception, e:
- print "Failed to parse (%s): %s" % (e, data)
+ print("Failed to parse (%s): %s" % (e, data))
return None
# Delete property from the top level
@@ -303,7 +303,7 @@
cua = prop.getValue().getValue()
record = directoryMap.lookupCUA(cua)
if record is None:
- # print "Can't find record for", cua
+ # print("Can't find record for", cua)
record = directoryMap.addRecord(cua=cua)
if record is None:
comp.removeProperty(prop)
@@ -371,10 +371,10 @@
'resources' : ('Resources', 'resource'),
}
- print "Fetching records from directory: %s" % (node,)
+ print("Fetching records from directory: %s" % (node,))
for internalType, (recordType, friendlyType) in self.strings.iteritems():
- print " %s..." % (internalType,)
+ print(" %s..." % (internalType,))
child = Popen(
args = [
"/usr/bin/dscl", "-plist", node, "-readall",
@@ -402,8 +402,8 @@
names=origRecordNames, emails=origEmails,
members=origMembers)
- print "Done."
- print ""
+ print("Done.")
+ print("")
def addRecord(self, internalType="users", guid=None, names=None,
emails=None, members=None, cua=None):
@@ -450,7 +450,7 @@
name = urllib.quote(name).lower()
keys.append(name)
except:
- # print "Failed to urllib.quote( ) %s. Skipping." % (name,)
+ # print("Failed to urllib.quote( ) %s. Skipping." % (name,))
pass
if emails:
for email in emails:
@@ -483,13 +483,13 @@
def printStats(self):
- print "Directory totals:"
+ print("Directory totals:")
for internalType, (recordType, ignore) in self.strings.iteritems():
- print " %s: %d" % (recordType, self.counts[internalType])
+ print(" %s: %d" % (recordType, self.counts[internalType]))
unknown = self.counts['unknown']
if unknown:
- print " Principals not found in directory: %d" % (unknown,)
+ print(" Principals not found in directory: %d" % (unknown,))
def dumpDsImports(self, dirPath):
if not os.path.exists(dirPath):
@@ -587,7 +587,7 @@
try:
text = text.encode('utf-8')
except UnicodeEncodeError:
- print "Failed to anonymize:", text
+ print("Failed to anonymize:", text)
text = "Anonymize me!"
h = hashlib.md5(text)
h = h.hexdigest()
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/backup_pg.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/backup_pg.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/backup_pg.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,6 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
from getopt import getopt, GetoptError
import os
@@ -38,19 +39,19 @@
def usage(e=None):
name = os.path.basename(sys.argv[0])
- print "usage: %s [options] command backup-file" % (name,)
- print ""
- print " Backup or restore calendar and addressbook data"
- print ""
- print "options:"
- print " -f --config <path>: Specify caldavd.plist configuration path"
- print " -h --help: print this help and exit"
- print " -v --verbose: print additional information"
- print ""
- print "commands:"
- print " backup: create backup-file in compressed tar format (tgz)"
- print " restore: restore from backup-file"
- print ""
+ print("usage: %s [options] command backup-file" % (name,))
+ print("")
+ print(" Backup or restore calendar and addressbook data")
+ print("")
+ print("options:")
+ print(" -f --config <path>: Specify caldavd.plist configuration path")
+ print(" -h --help: print this help and exit")
+ print(" -v --verbose: print additional information")
+ print("")
+ print("commands:")
+ print(" backup: create backup-file in compressed tar format (tgz)")
+ print(" restore: restore from backup-file")
+ print("")
if e:
sys.stderr.write("%s\n" % (e,))
@@ -75,14 +76,14 @@
]
try:
if verbose:
- print "\nDumping data to %s" % (dumpFile,)
- print "Executing: %s" % (" ".join(cmdArgs))
+ print("\nDumping data to %s" % (dumpFile,))
+ print("Executing: %s" % (" ".join(cmdArgs)))
out = subprocess.check_output(cmdArgs, stderr=subprocess.STDOUT)
if verbose:
- print out
+ print(out)
except subprocess.CalledProcessError, e:
if verbose:
- print e.output
+ print(e.output)
raise BackupError(
"%s failed:\n%s (exit code = %d)" %
(PGDUMP, e.output, e.returncode)
@@ -102,14 +103,14 @@
]
try:
if verbose:
- print "\nLoading data from %s" % (dumpFile,)
- print "Executing: %s" % (" ".join(cmdArgs))
+ print("\nLoading data from %s" % (dumpFile,))
+ print("Executing: %s" % (" ".join(cmdArgs)))
out = subprocess.check_output(cmdArgs, stderr=subprocess.STDOUT)
if verbose:
- print out
+ print(out)
except subprocess.CalledProcessError, e:
if verbose:
- print e.output
+ print(e.output)
raise BackupError(
"%s failed:\n%s (exit code = %d)" %
(PSQL, e.output, e.returncode)
@@ -168,24 +169,24 @@
dumpData(dumpPath, verbose=verbose)
if verbose:
- print "Creating %s" % (filename,)
+ print("Creating %s" % (filename,))
tar = tarfile.open(filename, "w:gz")
if verbose:
- print "Adding %s" % (serverRoot,)
+ print("Adding %s" % (serverRoot,))
tar.add(serverRoot)
if not dataRoot.startswith(serverRoot):
# DataRoot is not contained within ServerRoot (i.e, it's on
# another volume)
if verbose:
- print "Adding %s" % (dataRoot,)
+ print("Adding %s" % (dataRoot,))
tar.add(dataRoot)
tar.close()
if verbose:
- print "Done"
+ print("Done")
except BackupError, e:
error("Failed to dump database; error: %s" % (e,))
@@ -195,13 +196,13 @@
tar = tarfile.open(filename, "r:gz")
if verbose:
- print "Extracting from backup file: %s" % (filename,)
+ print("Extracting from backup file: %s" % (filename,))
tar.extractall(path="/")
loadData(dumpPath, verbose=verbose)
if verbose:
- print "Cleaning up database dump file: %s" % (dumpPath,)
+ print("Cleaning up database dump file: %s" % (dumpPath,))
os.remove(dumpPath)
except BackupError, e:
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/bootstrapdatabase.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/bootstrapdatabase.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/bootstrapdatabase.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
from getopt import getopt, GetoptError
import os
@@ -33,14 +34,14 @@
def usage(e=None):
name = os.path.basename(sys.argv[0])
- print "usage: %s [options] username" % (name,)
- print ""
- print " Bootstrap calendar server postgres database and schema"
- print ""
- print "options:"
- print " -h --help: print this help and exit"
- print " -v --verbose: print additional information"
- print ""
+ print("usage: %s [options] username" % (name,))
+ print("")
+ print(" Bootstrap calendar server postgres database and schema")
+ print("")
+ print("options:")
+ print(" -h --help: print this help and exit")
+ print(" -v --verbose: print additional information")
+ print("")
if e:
sys.stderr.write("%s\n" % (e,))
@@ -66,15 +67,15 @@
]
try:
if verbose:
- print "\nAttempting to create user..."
- print "Executing: %s" % (" ".join(cmdArgs))
+ print("\nAttempting to create user...")
+ print("Executing: %s" % (" ".join(cmdArgs)))
out = subprocess.check_output(cmdArgs, stderr=subprocess.STDOUT)
if verbose:
- print out
+ print(out)
return True
except subprocess.CalledProcessError, e:
if verbose:
- print e.output
+ print(e.output)
if "already exists" in e.output:
return False
raise BootstrapError(
@@ -98,15 +99,15 @@
]
try:
if verbose:
- print "\nAttempting to create database..."
- print "Executing: %s" % (" ".join(cmdArgs))
+ print("\nAttempting to create database...")
+ print("Executing: %s" % (" ".join(cmdArgs)))
out = subprocess.check_output(cmdArgs, stderr=subprocess.STDOUT)
if verbose:
- print out
+ print(out)
return True
except subprocess.CalledProcessError, e:
if verbose:
- print e.output
+ print(e.output)
if "already exists" in e.output:
return False
raise BootstrapError(
@@ -131,14 +132,14 @@
]
try:
if verbose:
- print "\nAttempting to read schema version..."
- print "Executing: %s" % (" ".join(cmdArgs))
+ print("\nAttempting to read schema version...")
+ print("Executing: %s" % (" ".join(cmdArgs)))
out = subprocess.check_output(cmdArgs, stderr=subprocess.STDOUT)
if verbose:
- print out
+ print(out)
except subprocess.CalledProcessError, e:
if verbose:
- print e.output
+ print(e.output)
raise BootstrapError(
"%s failed:\n%s (exit code = %d)" %
(PSQL, e.output, e.returncode)
@@ -167,16 +168,16 @@
]
try:
if verbose:
- print "Executing: %s" % (" ".join(cmdArgs))
+ print("Executing: %s" % (" ".join(cmdArgs)))
out = subprocess.check_output(cmdArgs, stderr=subprocess.STDOUT)
if verbose:
- print out
+ print(out)
if "already exists" in out:
return False
return True
except subprocess.CalledProcessError, e:
if verbose:
- print e.output
+ print(e.output)
raise BootstrapError(
"%s failed:\n%s (exit code = %d)" %
(PSQL, e.output, e.returncode)
@@ -216,9 +217,9 @@
try:
newlyCreated = createUser(verbose=verbose)
if newlyCreated:
- print "Database user '%s' created" % (USERNAME,)
+ print("Database user '%s' created" % (USERNAME,))
else:
- print "Database User '%s' exists" % (USERNAME,)
+ print("Database User '%s' exists" % (USERNAME,))
except BootstrapError, e:
error("Failed to create database user '%s': %s" % (USERNAME, e))
@@ -226,9 +227,9 @@
try:
newlyCreated = createDatabase(verbose=verbose)
if newlyCreated:
- print "Database '%s' created" % (DATABASENAME,)
+ print("Database '%s' created" % (DATABASENAME,))
else:
- print "Database '%s' exists" % (DATABASENAME,)
+ print("Database '%s' exists" % (DATABASENAME,))
except BootstrapError, e:
error("Failed to create database '%s': %s" % (DATABASENAME, e))
@@ -242,20 +243,20 @@
try:
data = open(SCHEMAFILE).read()
except IOError:
- print "Unable to open the schema file: %s" % (SCHEMAFILE,)
+ print("Unable to open the schema file: %s" % (SCHEMAFILE,))
else:
found = re.search("insert into CALENDARSERVER values \('VERSION', '(\d+)'\);", data)
if found is None:
- print "Schema is missing required schema VERSION insert statement: %s" % (SCHEMAFILE,)
+ print("Schema is missing required schema VERSION insert statement: %s" % (SCHEMAFILE,))
else:
required_version = int(found.group(1))
if version == required_version:
- print "Latest schema version (%d) is installed" % (version,)
+ print("Latest schema version (%d) is installed" % (version,))
elif version == 0: # No schema installed
installSchema(verbose=verbose)
version = getSchemaVersion(verbose=verbose)
- print "Successfully installed schema version %d" % (version,)
+ print("Successfully installed schema version %d" % (version,))
else: # upgrade needed
error(
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/calverify.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/calverify.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/calverify.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,7 +15,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
+from twistedcaldav.directory.directory import DirectoryService
+from twistedcaldav.datafilters.peruserdata import PerUserDataFilter
+
"""
This tool scans the calendar store to analyze organizer/attendee event
states to verify that the organizer's view of attendee state matches up
@@ -49,7 +53,7 @@
from pycalendar.timezone import PyCalendarTimezone
from twext.enterprise.dal.syntax import Select, Parameter, Count
from twisted.application.service import Service
-from twisted.internet.defer import inlineCallbacks, returnValue, succeed
+from twisted.internet.defer import inlineCallbacks, returnValue
from twisted.python import log, usage
from twisted.python.usage import Options
from twistedcaldav import caldavxml
@@ -191,12 +195,12 @@
if not hasattr(Component, "maxAlarmCounts"):
Component.hasDuplicateAlarms = new_hasDuplicateAlarms
-VERSION = "8"
+VERSION = "9"
def printusage(e=None):
if e:
- print e
- print ""
+ print(e)
+ print("")
try:
CalVerifyOptions().opt_help()
except SystemExit:
@@ -223,6 +227,7 @@
--mismatch : verify scheduling state.
--missing : display orphaned calendar homes - can be used.
with either --ical or --mismatch.
+--double : detect double-bookings.
--nuke PATH|RID : remove specific calendar resources - can
only be used by itself. PATH is the full
@@ -249,11 +254,22 @@
--details : log extended details on each mismatch.
--tzid : timezone to adjust details to.
+Options for --double:
+
+--uuid : only scan specified calendar homes. Can be a partial GUID
+ to scan all GUIDs with that as a prefix or "*" for all GUIDS
+ (that are marked as resources or locations in the directory).
+--tzid : timezone to adjust details to.
+--summary : report only which GUIDs have double-bookings - no details.
+--days : number of days ahead to scan [DEFAULT: 365]
+
CHANGES
v8: Detects ORGANIZER or ATTENDEE properties with mailto: calendar user
addresses for users that have valid directory records. Fix is to
replace the value with a urn:uuid: form.
+v9: Detects double-bookings.
+
""" % (VERSION,)
@@ -276,9 +292,11 @@
['nobase64', 'n', "Do not apply CALENDARSERVER-OLD-CUA base64 transform when fixing."],
['mismatch', 's', "Detect organizer/attendee mismatches."],
['missing', 'm', "Show 'orphaned' homes."],
+ ['double', 'd', "Detect double-bookings."],
['fix', 'x', "Fix problems."],
['verbose', 'v', "Verbose logging."],
['details', 'V', "Detailed logging."],
+ ['summary', 'S', "Summary of double-bookings."],
['tzid', 't', "Timezone to adjust displayed times to."],
]
@@ -286,7 +304,8 @@
['config', 'f', DEFAULT_CONFIG_FILE, "Specify caldavd.plist configuration path."],
['uuid', 'u', "", "Only check this user."],
['uid', 'U', "", "Only this event UID."],
- ['nuke', 'e', "", "Remove event given its path"]
+ ['nuke', 'e', "", "Remove event given its path."],
+ ['days', 'T', "365", "Number of days for scanning events into the future."]
]
@@ -321,25 +340,9 @@
class CalVerifyService(Service, object):
"""
- Service which runs, exports the appropriate records, then stops the reactor.
+ Base class for common service behaviors.
"""
- metadata = {
- "accessMode": "PUBLIC",
- "isScheduleObject": True,
- "scheduleTag": "abc",
- "scheduleEtags": (),
- "hasPrivateComment": False,
- }
-
- metadata_inbox = {
- "accessMode": "PUBLIC",
- "isScheduleObject": False,
- "scheduleTag": "",
- "scheduleEtags": (),
- "hasPrivateComment": False,
- }
-
def __init__(self, store, options, output, reactor, config):
super(CalVerifyService, self).__init__()
self.store = store
@@ -350,16 +353,9 @@
self._directory = None
self.cuaCache = {}
- self.validForCalendaringUUIDs = {}
self.results = {}
self.summary = []
- self.fixAttendeesForOrganizerMissing = 0
- self.fixAttendeesForOrganizerMismatch = 0
- self.fixOrganizersForAttendeeMissing = 0
- self.fixOrganizersForAttendeeMismatch = 0
- self.fixFailed = 0
- self.fixedAutoAccepts = []
self.total = 0
self.totalErrors = None
self.totalExceptions = None
@@ -373,25 +369,31 @@
self.doCalVerify()
+ def stopService(self):
+ """
+ Stop the service. Nothing to do; everything should be finished by this
+ time.
+ """
+ # TODO: stopping this service mid-export should really stop the export
+ # loop, but this is not implemented because nothing will actually do it
+ # except hitting ^C (which also calls reactor.stop(), so that will exit
+ # anyway).
+ pass
+
+
+ def title(self):
+ return ""
+
+
@inlineCallbacks
def doCalVerify(self):
"""
- Do the export, stopping the reactor when done.
+ Do the operation stopping the reactor when done.
"""
- self.output.write("\n---- CalVerify version: %s ----\n" % (VERSION,))
+ self.output.write("\n---- CalVerify %s version: %s ----\n" % (self.title(), VERSION,))
try:
- if self.options["nuke"]:
- yield self.doNuke()
- else:
- if self.options["missing"]:
- yield self.doOrphans()
-
- if self.options["mismatch"] or self.options["ical"] or self.options["badcua"]:
- yield self.doScan(self.options["ical"] or self.options["badcua"], self.options["mismatch"], self.options["fix"])
-
- self.printSummary()
-
+ yield self.doAction()
self.output.close()
except:
log.err()
@@ -399,154 +401,35 @@
self.reactor.stop()
- @inlineCallbacks
- def doNuke(self):
+ def directoryService(self):
"""
- Remove a resource using either its path or resource id. When doing this do not
- read the iCalendar data which may be corrupt.
+ Get an appropriate directory service for this L{CalVerifyService}'s
+ configuration, creating one first if necessary.
"""
+ if self._directory is None:
+ self._directory = getDirectory(self.config) #directoryFromConfig(self.config)
+ return self._directory
- self.output.write("\n---- Removing calendar resource ----\n")
- self.txn = self.store.newTransaction()
- nuke = self.options["nuke"]
- if nuke.startswith("/calendars/__uids__/"):
- pathbits = nuke.split("/")
- if len(pathbits) != 6:
- printusage("Not a valid calendar object resource path: %s" % (nuke,))
- homeName = pathbits[3]
- calendarName = pathbits[4]
- resourceName = pathbits[5]
-
- rid = yield self.getResourceID(homeName, calendarName, resourceName)
- if rid is None:
- yield self.txn.commit()
- self.txn = None
- self.output.write("\n")
- self.output.write("Path does not exist. Nothing nuked.\n")
- returnValue(None)
- rid = int(rid)
- else:
- try:
- rid = int(nuke)
- except ValueError:
- printusage("nuke argument must be a calendar object path or an SQL resource-id")
-
- if self.options["fix"]:
- result = yield self.fixByRemovingEvent(rid)
- if result:
- self.output.write("\n")
- self.output.write("Removed resource: %s.\n" % (rid,))
- else:
- self.output.write("\n")
- self.output.write("Resource: %s.\n" % (rid,))
- yield self.txn.commit()
- self.txn = None
-
-
@inlineCallbacks
- def doOrphans(self):
- """
- Report on home collections for which there are no directory records, or record is for user on
- a different pod, or a user not enabled for calendaring.
- """
- self.output.write("\n---- Finding calendar homes with missing or disabled directory records ----\n")
- self.txn = self.store.newTransaction()
+ def getAllHomeUIDs(self):
+ ch = schema.CALENDAR_HOME
+ rows = (yield Select(
+ [ch.OWNER_UID, ],
+ From=ch,
+ ).on(self.txn))
+ returnValue(tuple([uid[0] for uid in rows]))
- if self.options["verbose"]:
- t = time.time()
- uids = yield self.getAllHomeUIDs()
- if self.options["verbose"]:
- self.output.write("getAllHomeUIDs time: %.1fs\n" % (time.time() - t,))
- missing = []
- wrong_server = []
- disabled = []
- uids_len = len(uids)
- uids_div = 1 if uids_len < 100 else uids_len / 100
- self.addToSummary("Total Homes", uids_len)
- for ctr, uid in enumerate(uids):
- if self.options["verbose"] and divmod(ctr, uids_div)[1] == 0:
- self.output.write(("\r%d of %d (%d%%)" % (
- ctr + 1,
- uids_len,
- ((ctr + 1) * 100 / uids_len),
- )).ljust(80))
- self.output.flush()
-
- record = self.directoryService().recordWithGUID(uid)
- if record is None:
- contents = yield self.countHomeContents(uid)
- missing.append((uid, contents,))
- elif not record.thisServer():
- contents = yield self.countHomeContents(uid)
- wrong_server.append((uid, contents,))
- elif not record.enabledForCalendaring:
- contents = yield self.countHomeContents(uid)
- disabled.append((uid, contents,))
-
- # To avoid holding locks on all the rows scanned, commit every 100 resources
- if divmod(ctr, 100)[1] == 0:
- yield self.txn.commit()
- self.txn = self.store.newTransaction()
-
- yield self.txn.commit()
- self.txn = None
- if self.options["verbose"]:
- self.output.write("\r".ljust(80) + "\n")
-
- # Print table of results
- table = tables.Table()
- table.addHeader(("Owner UID", "Calendar Objects"))
- for uid, count in sorted(missing, key=lambda x: x[0]):
- table.addRow((
- uid,
- count,
- ))
-
- self.output.write("\n")
- self.output.write("Homes without a matching directory record (total=%d):\n" % (len(missing),))
- table.printTable(os=self.output)
- self.addToSummary("Homes without a matching directory record", len(missing), uids_len)
-
- # Print table of results
- table = tables.Table()
- table.addHeader(("Owner UID", "Calendar Objects"))
- for uid, count in sorted(wrong_server, key=lambda x: x[0]):
- record = self.directoryService().recordWithGUID(uid)
- table.addRow((
- "%s/%s (%s)" % (record.recordType if record else "-", record.shortNames[0] if record else "-", uid,),
- count,
- ))
-
- self.output.write("\n")
- self.output.write("Homes not hosted on this server (total=%d):\n" % (len(wrong_server),))
- table.printTable(os=self.output)
- self.addToSummary("Homes not hosted on this server", len(wrong_server), uids_len)
-
- # Print table of results
- table = tables.Table()
- table.addHeader(("Owner UID", "Calendar Objects"))
- for uid, count in sorted(disabled, key=lambda x: x[0]):
- record = self.directoryService().recordWithGUID(uid)
- table.addRow((
- "%s/%s (%s)" % (record.recordType if record else "-", record.shortNames[0] if record else "-", uid,),
- count,
- ))
-
- self.output.write("\n")
- self.output.write("Homes without an enabled directory record (total=%d):\n" % (len(disabled),))
- table.printTable(os=self.output)
- self.addToSummary("Homes without an enabled directory record", len(disabled), uids_len)
-
-
@inlineCallbacks
- def getAllHomeUIDs(self):
+ def getMatchingHomeUIDs(self, uuid):
ch = schema.CALENDAR_HOME
+ kwds = {"uuid": uuid}
rows = (yield Select(
[ch.OWNER_UID, ],
From=ch,
- ).on(self.txn))
+ Where=(ch.OWNER_UID.StartsWith(Parameter("uuid"))),
+ ).on(self.txn, **kwds))
returnValue(tuple([uid[0] for uid in rows]))
@@ -568,102 +451,6 @@
@inlineCallbacks
- def doScan(self, ical, mismatch, fix, start=None):
-
- self.output.write("\n---- Scanning calendar data ----\n")
-
- self.now = PyCalendarDateTime.getNowUTC()
- self.start = start if start is not None else PyCalendarDateTime.getToday()
- self.start.setDateOnly(False)
- self.end = self.start.duplicate()
- self.end.offsetYear(1)
- self.fix = fix
-
- self.tzid = PyCalendarTimezone(tzid=self.options["tzid"] if self.options["tzid"] else "America/Los_Angeles")
-
- self.txn = self.store.newTransaction()
-
- if self.options["verbose"]:
- t = time.time()
- descriptor = None
- if ical:
- if self.options["uuid"]:
- rows = yield self.getAllResourceInfoWithUUID(self.options["uuid"], inbox=True)
- descriptor = "getAllResourceInfoWithUUID"
- elif self.options["uid"]:
- rows = yield self.getAllResourceInfoWithUID(self.options["uid"], inbox=True)
- descriptor = "getAllResourceInfoWithUID"
- else:
- rows = yield self.getAllResourceInfo(inbox=True)
- descriptor = "getAllResourceInfo"
- else:
- if self.options["uid"]:
- rows = yield self.getAllResourceInfoWithUID(self.options["uid"])
- descriptor = "getAllResourceInfoWithUID"
- else:
- rows = yield self.getAllResourceInfoTimeRange(self.start)
- descriptor = "getAllResourceInfoTimeRange"
-
- yield self.txn.commit()
- self.txn = None
-
- if self.options["verbose"]:
- self.output.write("%s time: %.1fs\n" % (descriptor, time.time() - t,))
-
- self.total = len(rows)
- self.output.write("Number of events to process: %s\n" % (len(rows,)))
- self.results["Number of events to process"] = len(rows)
- self.addToSummary("Number of events to process", self.total)
-
- # Split into organizer events and attendee events
- self.organized = []
- self.organized_byuid = {}
- self.attended = []
- self.attended_byuid = collections.defaultdict(list)
- self.matched_attendee_to_organizer = collections.defaultdict(set)
- skipped, inboxes = self.buildResourceInfo(rows)
-
- self.output.write("Number of organizer events to process: %s\n" % (len(self.organized),))
- self.output.write("Number of attendee events to process: %s\n" % (len(self.attended,)))
- self.results["Number of organizer events to process"] = len(self.organized)
- self.results["Number of attendee events to process"] = len(self.attended)
- self.results["Number of skipped events"] = skipped
- self.results["Number of inbox events"] = inboxes
- self.addToSummary("Number of organizer events to process", len(self.organized), self.total)
- self.addToSummary("Number of attendee events to process", len(self.attended), self.total)
- self.addToSummary("Number of skipped events", skipped, self.total)
- if ical:
- self.addToSummary("Number of inbox events", inboxes, self.total)
- self.addSummaryBreak()
-
- if ical:
- yield self.calendarDataCheck(rows)
- elif mismatch:
- self.totalErrors = 0
- yield self.verifyAllAttendeesForOrganizer()
- yield self.verifyAllOrganizersForAttendee()
-
- # Need to add fix summary information
- if fix:
- self.addSummaryBreak()
- self.results["Fixed missing attendee events"] = self.fixAttendeesForOrganizerMissing
- self.results["Fixed mismatched attendee events"] = self.fixAttendeesForOrganizerMismatch
- self.results["Fixed missing organizer events"] = self.fixOrganizersForAttendeeMissing
- self.results["Fixed mismatched organizer events"] = self.fixOrganizersForAttendeeMismatch
- self.results["Fix failures"] = self.fixFailed
- self.results["Fixed Auto-Accepts"] = self.fixedAutoAccepts
- self.addToSummary("Fixed missing attendee events", self.fixAttendeesForOrganizerMissing)
- self.addToSummary("Fixed mismatched attendee events", self.fixAttendeesForOrganizerMismatch)
- self.addToSummary("Fixed missing organizer events", self.fixOrganizersForAttendeeMissing)
- self.addToSummary("Fixed mismatched organizer events", self.fixOrganizersForAttendeeMismatch)
- self.addToSummary("Fix failures", self.fixFailed)
-
- self.printAutoAccepts()
-
- yield succeed(None)
-
-
- @inlineCallbacks
def getAllResourceInfo(self, inbox=False):
co = schema.CALENDAR_OBJECT
cb = schema.CALENDAR_BIND
@@ -737,7 +524,7 @@
cb.CALENDAR_RESOURCE_NAME != "inbox").And(
co.ORGANIZER != "")).join(
tr, type="left", on=(co.RESOURCE_ID == tr.CALENDAR_OBJECT_RESOURCE_ID)),
- Where=(tr.START_DATE >= Parameter("Start")).Or(co.RECURRANCE_MAX == Parameter("Max")),
+ Where=(tr.START_DATE >= Parameter("Start")).Or(co.RECURRANCE_MAX <= Parameter("Start")),
GroupBy=(ch.OWNER_UID, co.RESOURCE_ID, co.ICALENDAR_UID, cb.CALENDAR_RESOURCE_NAME, co.MD5, co.ORGANIZER, co.CREATED, co.MODIFIED,),
).on(self.txn, **kwds))
returnValue(tuple(rows))
@@ -772,6 +559,44 @@
@inlineCallbacks
+ def getAllResourceInfoTimeRangeWithUUID(self, start, uuid):
+ co = schema.CALENDAR_OBJECT
+ cb = schema.CALENDAR_BIND
+ ch = schema.CALENDAR_HOME
+ tr = schema.TIME_RANGE
+
+ cojoin = (cb.CALENDAR_RESOURCE_ID == co.CALENDAR_RESOURCE_ID).And(
+ cb.BIND_MODE == _BIND_MODE_OWN).And(
+ cb.CALENDAR_RESOURCE_NAME != "inbox")
+
+ kwds = {
+ "Start" : pyCalendarTodatetime(start),
+ "Max" : pyCalendarTodatetime(PyCalendarDateTime(1900, 1, 1, 0, 0, 0)),
+ "UUID" : uuid,
+ }
+ rows = (yield Select(
+ [ch.OWNER_UID, co.RESOURCE_ID, co.ICALENDAR_UID, cb.CALENDAR_RESOURCE_NAME, co.MD5, co.ORGANIZER, co.CREATED, co.MODIFIED],
+ From=ch.join(
+ cb, type="inner", on=(ch.RESOURCE_ID == cb.CALENDAR_HOME_RESOURCE_ID)).join(
+ co, type="inner", on=cojoin),
+ Where=(co.ICALENDAR_UID.In(Select(
+ [co.ICALENDAR_UID],
+ From=ch.join(
+ cb, type="inner", on=(ch.RESOURCE_ID == cb.CALENDAR_HOME_RESOURCE_ID)).join(
+ co, type="inner", on=(cb.CALENDAR_RESOURCE_ID == co.CALENDAR_RESOURCE_ID).And(
+ cb.BIND_MODE == _BIND_MODE_OWN).And(
+ cb.CALENDAR_RESOURCE_NAME != "inbox").And(
+ co.ORGANIZER != "")).join(
+ tr, type="left", on=(co.RESOURCE_ID == tr.CALENDAR_OBJECT_RESOURCE_ID)),
+ Where=(ch.OWNER_UID == Parameter("UUID")).And((tr.START_DATE >= Parameter("Start")).Or(co.RECURRANCE_MAX <= Parameter("Start"))),
+ GroupBy=(ch.OWNER_UID, co.RESOURCE_ID, co.ICALENDAR_UID, cb.CALENDAR_RESOURCE_NAME, co.MD5, co.ORGANIZER, co.CREATED, co.MODIFIED,),
+ ))),
+ GroupBy=(ch.OWNER_UID, co.RESOURCE_ID, co.ICALENDAR_UID, cb.CALENDAR_RESOURCE_NAME, co.MD5, co.ORGANIZER, co.CREATED, co.MODIFIED,),
+ ).on(self.txn, **kwds))
+ returnValue(tuple(rows))
+
+
+ @inlineCallbacks
def getAllResourceInfoForResourceID(self, resid):
co = schema.CALENDAR_OBJECT
cb = schema.CALENDAR_BIND
@@ -812,57 +637,410 @@
returnValue(rows[0][0] if rows else None)
- def buildResourceInfo(self, rows, onlyOrganizer=False, onlyAttendee=False):
- skipped = 0
- inboxes = 0
- for owner, resid, uid, calname, md5, organizer, created, modified in rows:
+ @inlineCallbacks
+ def getCalendar(self, resid, doFix=False):
+ co = schema.CALENDAR_OBJECT
+ kwds = {"ResourceID" : resid}
+ rows = (yield Select(
+ [co.ICALENDAR_TEXT],
+ From=co,
+ Where=(
+ co.RESOURCE_ID == Parameter("ResourceID")
+ ),
+ ).on(self.txn, **kwds))
+ try:
+ caldata = PyCalendar.parseText(rows[0][0]) if rows else None
+ except PyCalendarError:
+ caltxt = rows[0][0] if rows else None
+ if caltxt:
+ caltxt = caltxt.replace("\r\n ", "")
+ if caltxt.find("CALENDARSERVER-OLD-CUA=\"//") != -1:
+ if doFix:
+ caltxt = (yield self.fixBadOldCua(resid, caltxt))
+ try:
+ caldata = PyCalendar.parseText(caltxt) if rows else None
+ except PyCalendarError:
+ self.parseError = "No fix bad CALENDARSERVER-OLD-CUA"
+ returnValue(None)
+ else:
+ self.parseError = "Bad CALENDARSERVER-OLD-CUA"
+ returnValue(None)
- # Skip owners not enabled for calendaring
- if not self.testForCalendaringUUID(owner):
- skipped += 1
- continue
+ self.parseError = "Failed to parse"
+ returnValue(None)
- # Skip inboxes
- if calname == "inbox":
- inboxes += 1
- continue
+ self.parseError = None
+ returnValue(caldata)
- # If targeting a specific organizer, skip events belonging to others
- if self.options["uuid"]:
- if not organizer.startswith("urn:uuid:") or self.options["uuid"] != organizer[9:]:
- continue
- # Cache organizer/attendee states
- if organizer.startswith("urn:uuid:") and owner == organizer[9:]:
- if not onlyAttendee:
- self.organized.append((owner, resid, uid, md5, organizer, created, modified,))
- self.organized_byuid[uid] = (owner, resid, uid, md5, organizer, created, modified,)
- else:
- if not onlyOrganizer:
- self.attended.append((owner, resid, uid, md5, organizer, created, modified,))
- self.attended_byuid[uid].append((owner, resid, uid, md5, organizer, created, modified,))
+ @inlineCallbacks
+ def getCalendarForOwnerByUID(self, owner, uid):
+ co = schema.CALENDAR_OBJECT
+ cb = schema.CALENDAR_BIND
+ ch = schema.CALENDAR_HOME
- return skipped, inboxes
+ kwds = {"OWNER": owner, "UID": uid}
+ rows = (yield Select(
+ [co.ICALENDAR_TEXT, co.RESOURCE_ID, co.CREATED, co.MODIFIED, ],
+ From=ch.join(
+ cb, type="inner", on=(ch.RESOURCE_ID == cb.CALENDAR_HOME_RESOURCE_ID)).join(
+ co, type="inner", on=(cb.CALENDAR_RESOURCE_ID == co.CALENDAR_RESOURCE_ID).And(
+ cb.BIND_MODE == _BIND_MODE_OWN).And(
+ cb.CALENDAR_RESOURCE_NAME != "inbox")),
+ Where=(ch.OWNER_UID == Parameter("OWNER")).And(co.ICALENDAR_UID == Parameter("UID")),
+ ).on(self.txn, **kwds))
+ try:
+ caldata = PyCalendar.parseText(rows[0][0]) if rows else None
+ except PyCalendarError:
+ returnValue((None, None, None, None,))
- def testForCalendaringUUID(self, uuid):
+ returnValue((caldata, rows[0][1], rows[0][2], rows[0][3],) if rows else (None, None, None, None,))
+
+
+ @inlineCallbacks
+ def fixBadOldCua(self, resid, caltxt):
"""
- Determine if the specified directory UUID is valid for calendaring. Keep a cache of
- valid and invalid so we can do this quickly.
+ Fix bad CALENDARSERVER-OLD-CUA lines and write fixed data to store. Assumes iCalendar data lines unfolded.
+ """
- @param uuid: the directory UUID to test
- @type uuid: C{str}
+ # Get store objects
+ homeID, calendarID = yield self.getAllResourceInfoForResourceID(resid)
+ home = yield self.txn.calendarHomeWithResourceID(homeID)
+ calendar = yield home.childWithID(calendarID)
+ calendarObj = yield calendar.objectResourceWithID(resid)
- @return: C{True} if valid, C{False} if not
+ # Do raw data fix one line at a time
+ caltxt = self.fixBadOldCuaLines(caltxt)
+
+ # Re-parse
+ try:
+ component = Component.fromString(caltxt)
+ except InvalidICalendarDataError:
+ returnValue(None)
+
+ # Write out fix, commit and get a new transaction
+ # Use _migrating to ignore possible overridden instance errors - we are either correcting or ignoring those
+ self.txn._migrating = True
+ component = yield calendarObj.setComponent(component)
+ yield self.txn.commit()
+ self.txn = self.store.newTransaction()
+
+ returnValue(caltxt)
+
+
+ def fixBadOldCuaLines(self, caltxt):
"""
+ Fix bad CALENDARSERVER-OLD-CUA lines. Assumes iCalendar data lines unfolded.
+ """
- if uuid not in self.validForCalendaringUUIDs:
- record = self.directoryService().recordWithGUID(uuid)
- self.validForCalendaringUUIDs[uuid] = record is not None and record.enabledForCalendaring and record.thisServer()
- return self.validForCalendaringUUIDs[uuid]
+ # Do raw data fix one line at a time
+ lines = caltxt.splitlines()
+ for ctr, line in enumerate(lines):
+ startpos = line.find(";CALENDARSERVER-OLD-CUA=\"//")
+ if startpos != -1:
+ endpos = line.find("urn:uuid:")
+ if endpos != -1:
+ endpos += len("urn:uuid:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\"")
+ badparam = line[startpos + len(";CALENDARSERVER-OLD-CUA=\""):endpos]
+ endbadparam = badparam.find(";")
+ if endbadparam != -1:
+ badparam = badparam[:endbadparam].replace("\\", "")
+ if badparam.find("8443") != -1:
+ badparam = "https:" + badparam
+ else:
+ badparam = "http:" + badparam
+ if self.options["nobase64"]:
+ badparam = "\"" + badparam + "\""
+ else:
+ badparam = "base64-%s" % (base64.b64encode(badparam),)
+ badparam = ";CALENDARSERVER-OLD-CUA=" + badparam
+ lines[ctr] = line[:startpos] + badparam + line[endpos:]
+ caltxt = "\r\n".join(lines) + "\r\n"
+ return caltxt
@inlineCallbacks
+ def removeEvent(self, resid):
+ """
+ Remove the calendar resource specified by resid - this is a force remove - no implicit
+ scheduling is required so we use store apis directly.
+ """
+
+ try:
+ homeID, calendarID = yield self.getAllResourceInfoForResourceID(resid)
+ home = yield self.txn.calendarHomeWithResourceID(homeID)
+ calendar = yield home.childWithID(calendarID)
+ calendarObj = yield calendar.objectResourceWithID(resid)
+ objname = calendarObj.name()
+ yield calendar.removeObjectResource(calendarObj)
+ yield self.txn.commit()
+ self.txn = self.store.newTransaction()
+
+ self.results.setdefault("Fix remove", set()).add((home.name(), calendar.name(), objname,))
+
+ returnValue(True)
+ except Exception, e:
+ print("Failed to remove resource whilst fixing: %d\n%s" % (resid, e,))
+ returnValue(False)
+
+
+ def logResult(self, key, value, total=None):
+ self.output.write("%s: %s\n" % (key, value,))
+ self.results[key] = value
+ self.addToSummary(key, value, total)
+
+
+ def addToSummary(self, title, count, total=None):
+ if total is not None:
+ percent = safePercent(count, total),
+ else:
+ percent = ""
+ self.summary.append((title, count, percent))
+
+
+ def addSummaryBreak(self):
+ self.summary.append(None)
+
+
+ def printSummary(self):
+ # Print summary of results
+ table = tables.Table()
+ table.addHeader(("Item", "Count", "%"))
+ table.setDefaultColumnFormats(
+ (
+ tables.Table.ColumnFormat("%s", tables.Table.ColumnFormat.LEFT_JUSTIFY),
+ tables.Table.ColumnFormat("%s", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
+ tables.Table.ColumnFormat("%.1f%%", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
+ )
+ )
+ for item in self.summary:
+ table.addRow(item)
+
+ if self.totalErrors is not None:
+ table.addRow(None)
+ table.addRow(("Total Errors", self.totalErrors, safePercent(self.totalErrors, self.total),))
+
+ self.output.write("\n")
+ self.output.write("Overall Summary:\n")
+ table.printTable(os=self.output)
+
+
+
+class NukeService(CalVerifyService):
+ """
+ Service which removes specific events.
+ """
+
+ def title(self):
+ return "Nuke Service"
+
+
+ @inlineCallbacks
+ def doAction(self):
+ """
+ Remove a resource using either its path or resource id. When doing this do not
+ read the iCalendar data which may be corrupt.
+ """
+
+ self.output.write("\n---- Removing calendar resource ----\n")
+ self.txn = self.store.newTransaction()
+
+ nuke = self.options["nuke"]
+ if nuke.startswith("/calendars/__uids__/"):
+ pathbits = nuke.split("/")
+ if len(pathbits) != 6:
+ printusage("Not a valid calendar object resource path: %s" % (nuke,))
+ homeName = pathbits[3]
+ calendarName = pathbits[4]
+ resourceName = pathbits[5]
+
+ rid = yield self.getResourceID(homeName, calendarName, resourceName)
+ if rid is None:
+ yield self.txn.commit()
+ self.txn = None
+ self.output.write("\n")
+ self.output.write("Path does not exist. Nothing nuked.\n")
+ returnValue(None)
+ rid = int(rid)
+ else:
+ try:
+ rid = int(nuke)
+ except ValueError:
+ printusage("nuke argument must be a calendar object path or an SQL resource-id")
+
+ if self.options["fix"]:
+ result = yield self.removeEvent(rid)
+ if result:
+ self.output.write("\n")
+ self.output.write("Removed resource: %s.\n" % (rid,))
+ else:
+ self.output.write("\n")
+ self.output.write("Resource: %s.\n" % (rid,))
+ yield self.txn.commit()
+ self.txn = None
+
+
+
+class OrphansService(CalVerifyService):
+ """
+ Service which detects orphaned calendar homes.
+ """
+
+ def title(self):
+ return "Orphans Service"
+
+
+ @inlineCallbacks
+ def doAction(self):
+ """
+ Report on home collections for which there are no directory records, or record is for user on
+ a different pod, or a user not enabled for calendaring.
+ """
+ self.output.write("\n---- Finding calendar homes with missing or disabled directory records ----\n")
+ self.txn = self.store.newTransaction()
+
+ if self.options["verbose"]:
+ t = time.time()
+ uids = yield self.getAllHomeUIDs()
+ if self.options["verbose"]:
+ self.output.write("getAllHomeUIDs time: %.1fs\n" % (time.time() - t,))
+ missing = []
+ wrong_server = []
+ disabled = []
+ uids_len = len(uids)
+ uids_div = 1 if uids_len < 100 else uids_len / 100
+ self.addToSummary("Total Homes", uids_len)
+
+ for ctr, uid in enumerate(uids):
+ if self.options["verbose"] and divmod(ctr, uids_div)[1] == 0:
+ self.output.write(("\r%d of %d (%d%%)" % (
+ ctr + 1,
+ uids_len,
+ ((ctr + 1) * 100 / uids_len),
+ )).ljust(80))
+ self.output.flush()
+
+ record = self.directoryService().recordWithGUID(uid)
+ if record is None:
+ contents = yield self.countHomeContents(uid)
+ missing.append((uid, contents,))
+ elif not record.thisServer():
+ contents = yield self.countHomeContents(uid)
+ wrong_server.append((uid, contents,))
+ elif not record.enabledForCalendaring:
+ contents = yield self.countHomeContents(uid)
+ disabled.append((uid, contents,))
+
+ # To avoid holding locks on all the rows scanned, commit every 100 resources
+ if divmod(ctr, 100)[1] == 0:
+ yield self.txn.commit()
+ self.txn = self.store.newTransaction()
+
+ yield self.txn.commit()
+ self.txn = None
+ if self.options["verbose"]:
+ self.output.write("\r".ljust(80) + "\n")
+
+ # Print table of results
+ table = tables.Table()
+ table.addHeader(("Owner UID", "Calendar Objects"))
+ for uid, count in sorted(missing, key=lambda x: x[0]):
+ table.addRow((
+ uid,
+ count,
+ ))
+
+ self.output.write("\n")
+ self.logResult("Homes without a matching directory record", len(missing), uids_len)
+ table.printTable(os=self.output)
+
+ # Print table of results
+ table = tables.Table()
+ table.addHeader(("Owner UID", "Calendar Objects"))
+ for uid, count in sorted(wrong_server, key=lambda x: x[0]):
+ record = self.directoryService().recordWithGUID(uid)
+ table.addRow((
+ "%s/%s (%s)" % (record.recordType if record else "-", record.shortNames[0] if record else "-", uid,),
+ count,
+ ))
+
+ self.output.write("\n")
+ self.logResult("Homes not hosted on this server", len(wrong_server), uids_len)
+ table.printTable(os=self.output)
+
+ # Print table of results
+ table = tables.Table()
+ table.addHeader(("Owner UID", "Calendar Objects"))
+ for uid, count in sorted(disabled, key=lambda x: x[0]):
+ record = self.directoryService().recordWithGUID(uid)
+ table.addRow((
+ "%s/%s (%s)" % (record.recordType if record else "-", record.shortNames[0] if record else "-", uid,),
+ count,
+ ))
+
+ self.output.write("\n")
+ self.logResult("Homes without an enabled directory record", len(disabled), uids_len)
+ table.printTable(os=self.output)
+
+ self.printSummary()
+
+
+
+class BadDataService(CalVerifyService):
+ """
+ Service which scans for bad calendar data.
+ """
+
+ def title(self):
+ return "Bad Data Service"
+
+
+ @inlineCallbacks
+ def doAction(self):
+
+ self.output.write("\n---- Scanning calendar data ----\n")
+
+ self.now = PyCalendarDateTime.getNowUTC()
+ self.start = PyCalendarDateTime.getToday()
+ self.start.setDateOnly(False)
+ self.end = self.start.duplicate()
+ self.end.offsetYear(1)
+ self.fix = self.options["fix"]
+
+ self.tzid = PyCalendarTimezone(tzid=self.options["tzid"] if self.options["tzid"] else "America/Los_Angeles")
+
+ self.txn = self.store.newTransaction()
+
+ if self.options["verbose"]:
+ t = time.time()
+ descriptor = None
+ if self.options["uuid"]:
+ rows = yield self.getAllResourceInfoWithUUID(self.options["uuid"], inbox=True)
+ descriptor = "getAllResourceInfoWithUUID"
+ elif self.options["uid"]:
+ rows = yield self.getAllResourceInfoWithUID(self.options["uid"], inbox=True)
+ descriptor = "getAllResourceInfoWithUID"
+ else:
+ rows = yield self.getAllResourceInfo(inbox=True)
+ descriptor = "getAllResourceInfo"
+
+ yield self.txn.commit()
+ self.txn = None
+
+ if self.options["verbose"]:
+ self.output.write("%s time: %.1fs\n" % (descriptor, time.time() - t,))
+
+ self.total = len(rows)
+ self.logResult("Number of events to process", self.total)
+ self.addSummaryBreak()
+
+ yield self.calendarDataCheck(rows)
+
+ self.printSummary()
+
+
+ @inlineCallbacks
def calendarDataCheck(self, rows):
"""
Check each calendar resource for valid iCalendar data.
@@ -886,7 +1064,7 @@
result = False
message = "Exception for validCalendarData"
if self.options["verbose"]:
- print e
+ print(e)
if not result:
results_bad.append((owner, uid, resid, message))
badlen += 1
@@ -934,12 +1112,10 @@
))
self.output.write("\n")
- self.output.write("Bad iCalendar data (total=%d):\n" % (len(results_bad),))
+ self.logResult("Bad iCalendar data", len(results_bad), total)
+ self.results["Bad iCalendar data"] = results_bad
table.printTable(os=self.output)
- self.results["Bad iCalendar data"] = results_bad
- self.addToSummary("Bad iCalendar data", len(results_bad), total)
-
if self.options["verbose"]:
diff_time = time.time() - t
self.output.write("Time: %.2f s Average: %.1f ms/resource\n" % (
@@ -1122,8 +1298,8 @@
self.txn._migrating = True
component = yield calendarObj.setComponent(component)
except Exception, e:
- print e, component
- print traceback.print_exc()
+ print(e, component)
+ print(traceback.print_exc())
result = False
message = "Exception fix: "
yield self.txn.commit()
@@ -1132,66 +1308,178 @@
returnValue((result, message,))
+
+class SchedulingMismatchService(CalVerifyService):
+ """
+ Service which detects mismatched scheduled events.
+ """
+
+ metadata = {
+ "accessMode": "PUBLIC",
+ "isScheduleObject": True,
+ "scheduleTag": "abc",
+ "scheduleEtags": (),
+ "hasPrivateComment": False,
+ }
+
+ metadata_inbox = {
+ "accessMode": "PUBLIC",
+ "isScheduleObject": False,
+ "scheduleTag": "",
+ "scheduleEtags": (),
+ "hasPrivateComment": False,
+ }
+
+ def __init__(self, store, options, output, reactor, config):
+ super(SchedulingMismatchService, self).__init__(store, options, output, reactor, config)
+
+ self.validForCalendaringUUIDs = {}
+
+ self.fixAttendeesForOrganizerMissing = 0
+ self.fixAttendeesForOrganizerMismatch = 0
+ self.fixOrganizersForAttendeeMissing = 0
+ self.fixOrganizersForAttendeeMismatch = 0
+ self.fixFailed = 0
+ self.fixedAutoAccepts = []
+
+
+ def title(self):
+ return "Scheduling Mismatch Service"
+
+
@inlineCallbacks
- def fixBadOldCua(self, resid, caltxt):
+ def doAction(self):
+
+ self.output.write("\n---- Scanning calendar data ----\n")
+
+ self.now = PyCalendarDateTime.getNowUTC()
+ self.start = self.options["start"] if "start" in self.options else PyCalendarDateTime.getToday()
+ self.start.setDateOnly(False)
+ self.end = self.start.duplicate()
+ self.end.offsetYear(1)
+ self.fix = self.options["fix"]
+
+ self.tzid = PyCalendarTimezone(tzid=self.options["tzid"] if self.options["tzid"] else "America/Los_Angeles")
+
+ self.txn = self.store.newTransaction()
+
+ if self.options["verbose"]:
+ t = time.time()
+ descriptor = None
+ if self.options["uid"]:
+ rows = yield self.getAllResourceInfoWithUID(self.options["uid"])
+ descriptor = "getAllResourceInfoWithUID"
+ elif self.options["uuid"]:
+ rows = yield self.getAllResourceInfoTimeRangeWithUUID(self.start, self.options["uuid"])
+ descriptor = "getAllResourceInfoTimeRangeWithUUID"
+ self.options["uuid"] = None
+ else:
+ rows = yield self.getAllResourceInfoTimeRange(self.start)
+ descriptor = "getAllResourceInfoTimeRange"
+
+ yield self.txn.commit()
+ self.txn = None
+
+ if self.options["verbose"]:
+ self.output.write("%s time: %.1fs\n" % (descriptor, time.time() - t,))
+
+ self.total = len(rows)
+ self.logResult("Number of events to process", self.total)
+
+ # Split into organizer events and attendee events
+ self.organized = []
+ self.organized_byuid = {}
+ self.attended = []
+ self.attended_byuid = collections.defaultdict(list)
+ self.matched_attendee_to_organizer = collections.defaultdict(set)
+ skipped, inboxes = self.buildResourceInfo(rows)
+
+ self.logResult("Number of organizer events to process", len(self.organized), self.total)
+ self.logResult("Number of attendee events to process", len(self.attended), self.total)
+ self.logResult("Number of skipped events", skipped, self.total)
+ self.logResult("Number of inbox events", inboxes)
+ self.addSummaryBreak()
+
+ self.totalErrors = 0
+ yield self.verifyAllAttendeesForOrganizer()
+ yield self.verifyAllOrganizersForAttendee()
+
+ # Need to add fix summary information
+ if self.fix:
+ self.addSummaryBreak()
+ self.logResult("Fixed missing attendee events", self.fixAttendeesForOrganizerMissing)
+ self.logResult("Fixed mismatched attendee events", self.fixAttendeesForOrganizerMismatch)
+ self.logResult("Fixed missing organizer events", self.fixOrganizersForAttendeeMissing)
+ self.logResult("Fixed mismatched organizer events", self.fixOrganizersForAttendeeMismatch)
+ self.logResult("Fix failures", self.fixFailed)
+ self.logResult("Fixed Auto-Accepts", len(self.fixedAutoAccepts))
+ self.results["Auto-Accepts"] = self.fixedAutoAccepts
+
+ self.printAutoAccepts()
+
+ self.printSummary()
+
+
+ def buildResourceInfo(self, rows, onlyOrganizer=False, onlyAttendee=False):
"""
- Fix bad CALENDARSERVER-OLD-CUA lines and write fixed data to store. Assumes iCalendar data lines unfolded.
+ For each resource, determine whether it is an organizer or attendee event, and also
+ cache the attendee partstats.
+
+ @param rows: set of DB query rows
+ @type rows: C{list}
+ @param onlyOrganizer: whether organizer information only is required
+ @type onlyOrganizer: C{bool}
+ @param onlyAttendee: whether attendee information only is required
+ @type onlyAttendee: C{bool}
"""
- # Get store objects
- homeID, calendarID = yield self.getAllResourceInfoForResourceID(resid)
- home = yield self.txn.calendarHomeWithResourceID(homeID)
- calendar = yield home.childWithID(calendarID)
- calendarObj = yield calendar.objectResourceWithID(resid)
+ skipped = 0
+ inboxes = 0
+ for owner, resid, uid, calname, md5, organizer, created, modified in rows:
- # Do raw data fix one line at a time
- caltxt = self.fixBadOldCuaLines(caltxt)
+ # Skip owners not enabled for calendaring
+ if not self.testForCalendaringUUID(owner):
+ skipped += 1
+ continue
- # Re-parse
- try:
- component = Component.fromString(caltxt)
- except InvalidICalendarDataError:
- returnValue(None)
+ # Skip inboxes
+ if calname == "inbox":
+ inboxes += 1
+ continue
- # Write out fix, commit and get a new transaction
- # Use _migrating to ignore possible overridden instance errors - we are either correcting or ignoring those
- self.txn._migrating = True
- component = yield calendarObj.setComponent(component)
- yield self.txn.commit()
- self.txn = self.store.newTransaction()
+ # If targeting a specific organizer, skip events belonging to others
+ if self.options["uuid"]:
+ if not organizer.startswith("urn:uuid:") or self.options["uuid"] != organizer[9:]:
+ continue
- returnValue(caltxt)
+ # Cache organizer/attendee states
+ if organizer.startswith("urn:uuid:") and owner == organizer[9:]:
+ if not onlyAttendee:
+ self.organized.append((owner, resid, uid, md5, organizer, created, modified,))
+ self.organized_byuid[uid] = (owner, resid, uid, md5, organizer, created, modified,)
+ else:
+ if not onlyOrganizer:
+ self.attended.append((owner, resid, uid, md5, organizer, created, modified,))
+ self.attended_byuid[uid].append((owner, resid, uid, md5, organizer, created, modified,))
+ return skipped, inboxes
- def fixBadOldCuaLines(self, caltxt):
+
+ def testForCalendaringUUID(self, uuid):
"""
- Fix bad CALENDARSERVER-OLD-CUA lines. Assumes iCalendar data lines unfolded.
+ Determine if the specified directory UUID is valid for calendaring. Keep a cache of
+ valid and invalid so we can do this quickly.
+
+ @param uuid: the directory UUID to test
+ @type uuid: C{str}
+
+ @return: C{True} if valid, C{False} if not
"""
- # Do raw data fix one line at a time
- lines = caltxt.splitlines()
- for ctr, line in enumerate(lines):
- startpos = line.find(";CALENDARSERVER-OLD-CUA=\"//")
- if startpos != -1:
- endpos = line.find("urn:uuid:")
- if endpos != -1:
- endpos += len("urn:uuid:XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\"")
- badparam = line[startpos + len(";CALENDARSERVER-OLD-CUA=\""):endpos]
- endbadparam = badparam.find(";")
- if endbadparam != -1:
- badparam = badparam[:endbadparam].replace("\\", "")
- if badparam.find("8443") != -1:
- badparam = "https:" + badparam
- else:
- badparam = "http:" + badparam
- if self.options["nobase64"]:
- badparam = "\"" + badparam + "\""
- else:
- badparam = "base64-%s" % (base64.b64encode(badparam),)
- badparam = ";CALENDARSERVER-OLD-CUA=" + badparam
- lines[ctr] = line[:startpos] + badparam + line[endpos:]
- caltxt = "\r\n".join(lines) + "\r\n"
- return caltxt
+ if uuid not in self.validForCalendaringUUIDs:
+ record = self.directoryService().recordWithGUID(uuid)
+ self.validForCalendaringUUIDs[uuid] = record is not None and record.enabledForCalendaring and record.thisServer()
+ return self.validForCalendaringUUIDs[uuid]
@inlineCallbacks
@@ -1214,7 +1502,6 @@
# Test organized events
t = time.time()
for ctr, organizerEvent in enumerate(self.organized):
-
if self.options["verbose"] and divmod(ctr, organizer_div)[1] == 0:
self.output.write(("\r%d of %d (%d%%) Missing: %d Mismatched: %s" % (
ctr + 1,
@@ -1277,7 +1564,7 @@
eachAttendeesOwnStatus[organizerAttendee] = self.buildAttendeeStates(calendar, self.start, self.end, attendee_only=organizerAttendee)
attendeeResIDs[(organizerAttendee, uid)] = attresid
attendeeCreatedModified[organizerAttendee] = (att_created, att_modified,)
- #print "Reloaded missing attendee data"
+ #print("Reloaded missing attendee data")
# If an entry for the attendee exists, then check whether attendee status matches
if organizerAttendee in eachAttendeesOwnStatus:
@@ -1348,9 +1635,8 @@
))
self.output.write("\n")
- self.output.write("Events missing from Attendee's calendars (total=%d):\n" % (len(results_missing),))
+ self.logResult("Events missing from Attendee's calendars", len(results_missing), self.total)
table.printTable(os=self.output)
- self.addToSummary("Events missing from Attendee's calendars", len(results_missing), self.total)
self.totalErrors += len(results_missing)
# Print table of results
@@ -1374,9 +1660,8 @@
))
self.output.write("\n")
- self.output.write("Events mismatched between Organizer's and Attendee's calendars (total=%d):\n" % (len(results_mismatch),))
+ self.logResult("Events mismatched between Organizer's and Attendee's calendars", len(results_mismatch), self.total)
table.printTable(os=self.output)
- self.addToSummary("Events mismatched between Organizer's and Attendee's calendars", len(results_mismatch), self.total)
self.totalErrors += len(results_mismatch)
@@ -1438,7 +1723,7 @@
self.buildResourceInfo(rows, onlyOrganizer=True)
#if uid in self.organized_byuid:
- # print "Reloaded missing organizer data: %s" % (uid,)
+ # print("Reloaded missing organizer data: %s" % (uid,))
if uid not in self.organized_byuid:
@@ -1452,7 +1737,7 @@
# If there is a miss we fix by removing the attendee data
if self.fix:
# This is where we attempt a fix
- fix_result = (yield self.fixByRemovingEvent(resid))
+ fix_result = (yield self.removeEvent(resid))
if fix_result:
self.fixOrganizersForAttendeeMissing += 1
else:
@@ -1525,9 +1810,8 @@
))
self.output.write("\n")
- self.output.write("Attendee events mismatched in Organizer's calendar (total=%d):\n" % (len(mismatched),))
+ self.logResult("Attendee events mismatched in Organizer's calendar", len(mismatched), self.total)
table.printTable(os=self.output)
- self.addToSummary("Attendee events mismatched in Organizer's calendar", len(mismatched), self.total)
self.totalErrors += len(mismatched)
@@ -1556,7 +1840,7 @@
# Handle the case where the attendee is not actually in the organizer event at all by
# removing the attendee event instead of re-inviting
if itipmsg.resourceUID() is None:
- yield self.fixByRemovingEvent(attresid)
+ yield self.removeEvent(attresid)
returnValue(True)
# Convert iTip message into actual calendar data - just remove METHOD
@@ -1624,7 +1908,7 @@
returnValue(True)
except Exception, e:
- print "Failed to fix resource: %d for attendee: %s\n%s" % (orgresid, attendee, e,)
+ print("Failed to fix resource: %d for attendee: %s\n%s" % (orgresid, attendee, e,))
returnValue(False)
@@ -1647,66 +1931,6 @@
returnValue(None)
- @inlineCallbacks
- def fixByRemovingEvent(self, resid):
- """
- Remove the calendar resource specified by resid - this is a force remove - no implicit
- scheduling is required so we use store apis directly.
- """
-
- try:
- homeID, calendarID = yield self.getAllResourceInfoForResourceID(resid)
- home = yield self.txn.calendarHomeWithResourceID(homeID)
- calendar = yield home.childWithID(calendarID)
- calendarObj = yield calendar.objectResourceWithID(resid)
- objname = calendarObj.name()
- yield calendar.removeObjectResource(calendarObj)
- yield self.txn.commit()
- self.txn = self.store.newTransaction()
-
- self.results.setdefault("Fix remove", set()).add((home.name(), calendar.name(), objname,))
-
- returnValue(True)
- except Exception, e:
- print "Failed to remove resource whilst fixing: %d\n%s" % (resid, e,)
- returnValue(False)
-
-
- def addToSummary(self, title, count, total=None):
- if total is not None:
- percent = safePercent(count, total),
- else:
- percent = ""
- self.summary.append((title, count, percent))
-
-
- def addSummaryBreak(self):
- self.summary.append(None)
-
-
- def printSummary(self):
- # Print summary of results
- table = tables.Table()
- table.addHeader(("Item", "Count", "%"))
- table.setDefaultColumnFormats(
- (
- tables.Table.ColumnFormat("%s", tables.Table.ColumnFormat.LEFT_JUSTIFY),
- tables.Table.ColumnFormat("%d", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
- tables.Table.ColumnFormat("%.1f%%", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
- )
- )
- for item in self.summary:
- table.addRow(item)
-
- if self.totalErrors is not None:
- table.addRow(None)
- table.addRow(("Total Errors", self.totalErrors, safePercent(self.totalErrors, self.total),))
-
- self.output.write("\n")
- self.output.write("Overall Summary:\n")
- table.printTable(os=self.output)
-
-
def printAutoAccepts(self):
# Print summary of results
table = tables.Table()
@@ -1725,71 +1949,11 @@
table.printTable(os=self.output)
- @inlineCallbacks
- def getCalendar(self, resid, doFix=False):
- co = schema.CALENDAR_OBJECT
- kwds = {"ResourceID" : resid}
- rows = (yield Select(
- [co.ICALENDAR_TEXT],
- From=co,
- Where=(
- co.RESOURCE_ID == Parameter("ResourceID")
- ),
- ).on(self.txn, **kwds))
- try:
- caldata = PyCalendar.parseText(rows[0][0]) if rows else None
- except PyCalendarError:
- caltxt = rows[0][0] if rows else None
- if caltxt:
- caltxt = caltxt.replace("\r\n ", "")
- if caltxt.find("CALENDARSERVER-OLD-CUA=\"//") != -1:
- if doFix:
- caltxt = (yield self.fixBadOldCua(resid, caltxt))
- try:
- caldata = PyCalendar.parseText(caltxt) if rows else None
- except PyCalendarError:
- self.parseError = "No fix bad CALENDARSERVER-OLD-CUA"
- returnValue(None)
- else:
- self.parseError = "Bad CALENDARSERVER-OLD-CUA"
- returnValue(None)
-
- self.parseError = "Failed to parse"
- returnValue(None)
-
- self.parseError = None
- returnValue(caldata)
-
-
- @inlineCallbacks
- def getCalendarForOwnerByUID(self, owner, uid):
- co = schema.CALENDAR_OBJECT
- cb = schema.CALENDAR_BIND
- ch = schema.CALENDAR_HOME
-
- kwds = {"OWNER": owner, "UID": uid}
- rows = (yield Select(
- [co.ICALENDAR_TEXT, co.RESOURCE_ID, co.CREATED, co.MODIFIED, ],
- From=ch.join(
- cb, type="inner", on=(ch.RESOURCE_ID == cb.CALENDAR_HOME_RESOURCE_ID)).join(
- co, type="inner", on=(cb.CALENDAR_RESOURCE_ID == co.CALENDAR_RESOURCE_ID).And(
- cb.BIND_MODE == _BIND_MODE_OWN).And(
- cb.CALENDAR_RESOURCE_NAME != "inbox")),
- Where=(ch.OWNER_UID == Parameter("OWNER")).And(co.ICALENDAR_UID == Parameter("UID")),
- ).on(self.txn, **kwds))
-
- try:
- caldata = PyCalendar.parseText(rows[0][0]) if rows else None
- except PyCalendarError:
- returnValue((None, None, None, None,))
-
- returnValue((caldata, rows[0][1], rows[0][2], rows[0][3],) if rows else (None, None, None, None,))
-
-
def masterComponent(self, calendar):
"""
Return the master iCal component in this calendar.
- @return: the L{Component} for the master component,
+
+ @return: the L{PyCalendarComponent} for the master component,
or C{None} if there isn't one.
"""
for component in calendar.getComponents(definitions.cICalComponent_VEVENT):
@@ -1882,32 +2046,319 @@
component.replaceProperty(Property("TRANSP", "TRANSPARENT" if addTransp else "OPAQUE"))
- def directoryService(self):
- """
- Get an appropriate directory service for this L{CalVerifyService}'s
- configuration, creating one first if necessary.
- """
- if self._directory is None:
- self._directory = getDirectory(self.config) #directoryFromConfig(self.config)
- return self._directory
+class DoubleBookingService(CalVerifyService):
+ """
+ Service which detects double-booked events.
+ """
- def stopService(self):
+ def title(self):
+ return "Double Booking Service"
+
+
+ @inlineCallbacks
+ def doAction(self):
+
+ if self.options["fix"]:
+ self.output.write("\nFixing is not supported.\n")
+ returnValue(None)
+
+ self.output.write("\n---- Scanning calendar data ----\n")
+
+ self.tzid = PyCalendarTimezone(tzid=self.options["tzid"] if self.options["tzid"] else "America/Los_Angeles")
+ self.now = PyCalendarDateTime.getNowUTC()
+ self.start = PyCalendarDateTime.getToday()
+ self.start.setDateOnly(False)
+ self.start.setTimezone(self.tzid)
+ self.end = self.start.duplicate()
+ self.end.offsetYear(1)
+ self.fix = self.options["fix"]
+
+ if self.options["verbose"] and self.options["summary"]:
+ ot = time.time()
+
+ # Check loop over uuid
+ UUIDDetails = collections.namedtuple("UUIDDetails", ("uuid", "rname", "auto", "doubled",))
+ self.uuid_details = []
+ if len(self.options["uuid"]) != 36:
+ self.txn = self.store.newTransaction()
+ if self.options["uuid"]:
+ homes = yield self.getMatchingHomeUIDs(self.options["uuid"])
+ else:
+ homes = yield self.getAllHomeUIDs()
+ yield self.txn.commit()
+ self.txn = None
+ uuids = []
+ for uuid in sorted(homes):
+ record = self.directoryService().recordWithGUID(uuid)
+ if record is not None and record.recordType in (DirectoryService.recordType_locations, DirectoryService.recordType_resources):
+ uuids.append(uuid)
+ else:
+ uuids = [self.options["uuid"], ]
+
+ count = 0
+ for uuid in uuids:
+ self.results = {}
+ self.summary = []
+ self.total = 0
+ count += 1
+
+ record = self.directoryService().recordWithGUID(uuid)
+ if record is None:
+ continue
+ if not record.thisServer() or not record.enabledForCalendaring:
+ continue
+
+ rname = record.fullName
+ auto = record.autoSchedule
+
+ if len(uuids) > 1 and not self.options["summary"]:
+ self.output.write("\n\n-----------------------------\n")
+
+ self.txn = self.store.newTransaction()
+
+ if self.options["verbose"]:
+ t = time.time()
+ rows = yield self.getTimeRangeInfoWithUUID(uuid, self.start)
+ descriptor = "getTimeRangeInfoWithUUID"
+
+ yield self.txn.commit()
+ self.txn = None
+
+ if self.options["verbose"]:
+ if not self.options["summary"]:
+ self.output.write("%s time: %.1fs\n" % (descriptor, time.time() - t,))
+ else:
+ self.output.write("%s (%d/%d)" % (uuid, count, len(uuids),))
+ self.output.flush()
+
+ self.total = len(rows)
+ if not self.options["summary"]:
+ self.logResult("UUID to process", uuid)
+ self.logResult("Record name", rname)
+ self.logResult("Auto-schedule", "True" if auto else "False")
+ self.addSummaryBreak()
+ self.logResult("Number of events to process", self.total)
+
+ if rows:
+ if not self.options["summary"]:
+ self.addSummaryBreak()
+ doubled = yield self.doubleBookCheck(rows, uuid, self.start)
+ else:
+ doubled = False
+
+ self.uuid_details.append(UUIDDetails(uuid, rname, auto, doubled))
+
+ if not self.options["summary"]:
+ self.printSummary()
+ else:
+ self.output.write(" - %s\n" % ("Double-booked" if doubled else "OK",))
+ self.output.flush()
+
+ if self.options["summary"]:
+ table = tables.Table()
+ table.addHeader(("GUID", "Name", "Auto-Schedule", "Double-Booked",))
+ doubled = 0
+ for item in sorted(self.uuid_details):
+ if not item.doubled:
+ continue
+ table.addRow((
+ item.uuid,
+ item.rname,
+ item.auto,
+ item.doubled,
+ ))
+ doubled += 1
+ table.addFooter(("Total", "", "", "%d of %d" % (doubled, len(self.uuid_details),),))
+ self.output.write("\n")
+ table.printTable(os=self.output)
+
+ if self.options["verbose"]:
+ self.output.write("%s time: %.1fs\n" % ("Summary", time.time() - ot,))
+
+
+ @inlineCallbacks
+ def getTimeRangeInfoWithUUID(self, uuid, start):
+ co = schema.CALENDAR_OBJECT
+ cb = schema.CALENDAR_BIND
+ ch = schema.CALENDAR_HOME
+ tr = schema.TIME_RANGE
+ kwds = {
+ "uuid": uuid,
+ "Start" : pyCalendarTodatetime(start),
+ }
+ rows = (yield Select(
+ [co.RESOURCE_ID, ],
+ From=ch.join(
+ cb, type="inner", on=(ch.RESOURCE_ID == cb.CALENDAR_HOME_RESOURCE_ID)).join(
+ co, type="inner", on=(cb.CALENDAR_RESOURCE_ID == co.CALENDAR_RESOURCE_ID).And(
+ cb.BIND_MODE == _BIND_MODE_OWN).And(
+ cb.CALENDAR_RESOURCE_NAME != "inbox").And(
+ co.ORGANIZER != "")).join(
+ tr, type="left", on=(co.RESOURCE_ID == tr.CALENDAR_OBJECT_RESOURCE_ID)),
+ Where=(ch.OWNER_UID == Parameter("uuid")).And((tr.START_DATE >= Parameter("Start")).Or(co.RECURRANCE_MAX <= Parameter("Start"))),
+ Distinct=True,
+ ).on(self.txn, **kwds))
+ returnValue(tuple(rows))
+
+
+ @inlineCallbacks
+ def doubleBookCheck(self, rows, uuid, start):
"""
- Stop the service. Nothing to do; everything should be finished by this
- time.
+ Check each calendar resource by expanding instances within the next year, and looking for
+ any that overlap with status not CANCELLED and PARTSTAT ACCEPTED.
"""
- # TODO: stopping this service mid-export should really stop the export
- # loop, but this is not implemented because nothing will actually do it
- # except hitting ^C (which also calls reactor.stop(), so that will exit
- # anyway).
+ if not self.options["summary"]:
+ self.output.write("\n---- Checking instances for double-booking ----\n")
+ self.txn = self.store.newTransaction()
+ if self.options["verbose"]:
+ t = time.time()
+ InstanceDetails = collections.namedtuple("InstanceDetails", ("resid", "uid", "start", "end", "organizer", "summary",))
+
+ end = start.duplicate()
+ end.offsetDay(int(self.options["days"]))
+ count = 0
+ total = len(rows)
+ total_instances = 0
+ booked_instances = 0
+ details = []
+ rjust = 10
+ tzid = None
+ hasFloating = False
+ for resid in rows:
+ resid = resid[0]
+ caldata = yield self.getCalendar(resid, self.fix)
+ if caldata is None:
+ if self.parseError:
+ returnValue((False, self.parseError))
+ else:
+ returnValue((True, "Nothing to scan"))
+
+ cal = Component(None, pycalendar=caldata)
+ cal = PerUserDataFilter(uuid).filter(cal)
+ uid = cal.resourceUID()
+ instances = cal.expandTimeRanges(end, start, ignoreInvalidInstances=False)
+ count += 1
+
+ for instance in instances.instances.values():
+ total_instances += 1
+
+ # See if it is CANCELLED or TRANSPARENT
+ if instance.component.propertyValue("STATUS") == "CANCELLED":
+ continue
+ if instance.component.propertyValue("TRANSP") == "TRANSPARENT":
+ continue
+ dtstart = instance.component.propertyValue("DTSTART")
+ if tzid is None and dtstart.getTimezoneID():
+ tzid = PyCalendarTimezone(tzid=dtstart.getTimezoneID())
+ hasFloating |= dtstart.isDateOnly() or dtstart.floating()
+
+ details.append(InstanceDetails(resid, uid, instance.start, instance.end, instance.component.getOrganizer(), instance.component.propertyValue("SUMMARY")))
+ booked_instances += 1
+
+ if self.options["verbose"] and not self.options["summary"]:
+ if count == 1:
+ self.output.write("Instances".rjust(rjust) + "Current".rjust(rjust) + "Total".rjust(rjust) + "Complete".rjust(rjust) + "\n")
+ if divmod(count, 100)[1] == 0:
+ self.output.write((
+ "\r" +
+ ("%s" % total_instances).rjust(rjust) +
+ ("%s" % count).rjust(rjust) +
+ ("%s" % total).rjust(rjust) +
+ ("%d%%" % safePercent(count, total)).rjust(rjust)
+ ).ljust(80))
+ self.output.flush()
+
+ # To avoid holding locks on all the rows scanned, commit every 100 resources
+ if divmod(count, 100)[1] == 0:
+ yield self.txn.commit()
+ self.txn = self.store.newTransaction()
+
+ yield self.txn.commit()
+ self.txn = None
+ if self.options["verbose"] and not self.options["summary"]:
+ self.output.write((
+ "\r" +
+ ("%s" % total_instances).rjust(rjust) +
+ ("%s" % count).rjust(rjust) +
+ ("%s" % total).rjust(rjust) +
+ ("%d%%" % safePercent(count, total)).rjust(rjust)
+ ).ljust(80) + "\n")
+
+ if not self.options["summary"]:
+ self.logResult("Number of instances in time-range", total_instances)
+ self.logResult("Number of booked instances", booked_instances)
+
+ # Adjust floating and sort
+ if hasFloating and tzid is not None:
+ utc = PyCalendarTimezone(utc=True)
+ for item in details:
+ if item.start.floating():
+ item.start.setTimezone(tzid)
+ item.start.adjustTimezone(utc)
+ if item.end.floating():
+ item.end.setTimezone(tzid)
+ item.end.adjustTimezone(utc)
+ details.sort(key=lambda x: x.start)
+
+ # Now look for double-bookings
+ DoubleBookedDetails = collections.namedtuple("DoubleBookedDetails", ("resid1", "uid1", "resid2", "uid2", "start",))
+ double_booked = []
+ current = details[0] if details else None
+ for next in details[1:]:
+ if current.end > next.start and current.resid != next.resid and not (current.organizer == next.organizer and current.summary == next.summary):
+ dt = next.start.duplicate()
+ dt.adjustTimezone(self.tzid)
+ double_booked.append(DoubleBookedDetails(current.resid, current.uid, next.resid, next.uid, dt,))
+ current = next
+
+ # Print table of results
+ if double_booked and not self.options["summary"]:
+ table = tables.Table()
+ table.addHeader(("RID #1", "UID #1", "RID #2", "UID #2", "Start",))
+ previous1 = None
+ previous2 = None
+ unique_events = 0
+ for item in sorted(double_booked):
+ if previous1 != item.resid1:
+ unique_events += 1
+ resid1 = item.resid1 if previous1 != item.resid1 else "."
+ uid1 = item.uid1 if previous1 != item.resid1 else "."
+ resid2 = item.resid2 if previous2 != item.resid2 else "."
+ uid2 = item.uid2 if previous2 != item.resid2 else "."
+ table.addRow((
+ resid1,
+ uid1,
+ resid2,
+ uid2,
+ item.start,
+ ))
+ previous1 = item.resid1
+ previous2 = item.resid2
+
+ self.output.write("\n")
+ self.logResult("Number of double-bookings", len(double_booked))
+ self.logResult("Number of unique double-bookings", unique_events)
+ table.printTable(os=self.output)
+
+ self.results["Double-bookings"] = double_booked
+
+ if self.options["verbose"] and not self.options["summary"]:
+ diff_time = time.time() - t
+ self.output.write("Time: %.2f s Average: %.1f ms/resource\n" % (
+ diff_time,
+ safePercent(diff_time, total, 1000.0),
+ ))
+
+ returnValue(len(double_booked) != 0)
+
+
+
def main(argv=sys.argv, stderr=sys.stderr, reactor=None):
- """
- Do the export.
- """
+
if reactor is None:
from twisted.internet import reactor
options = CalVerifyOptions()
@@ -1926,9 +2377,18 @@
def makeService(store):
from twistedcaldav.config import config
config.TransactionTimeoutSeconds = 0
- return CalVerifyService(store, options, output, reactor, config)
+ if options["nuke"]:
+ return NukeService(store, options, output, reactor, config)
+ elif options["missing"]:
+ return OrphansService(store, options, output, reactor, config)
+ elif options["ical"] or options["badcua"]:
+ return BadDataService(store, options, output, reactor, config)
+ elif options["mismatch"]:
+ return SchedulingMismatchService(store, options, output, reactor, config)
+ elif options["double"]:
+ return DoubleBookingService(store, options, output, reactor, config)
- utilityMain(options['config'], makeService, reactor, verbose=options['debug'])
+ utilityMain(options['config'], makeService, reactor)
if __name__ == '__main__':
main()
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/calverify_diff.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/calverify_diff.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/calverify_diff.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,6 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import getopt
import sys
@@ -77,16 +78,16 @@
def diff(results1, results2):
- print "\n\nEvents missing from Attendee's calendars"
+ print("\n\nEvents missing from Attendee's calendars")
diffSets(results1["table1"], results2["table1"])
- print "\n\nEvents mismatched between Organizer's and Attendee's calendars"
+ print("\n\nEvents mismatched between Organizer's and Attendee's calendars")
diffSets(results1["table2"], results2["table2"])
- print "\n\nAttendee events missing in Organizer's calendar"
+ print("\n\nAttendee events missing in Organizer's calendar")
diffSets(results1["table3"], results2["table3"])
- print "\n\nAttendee events mismatched in Organizer's calendar"
+ print("\n\nAttendee events mismatched in Organizer's calendar")
diffSets(results1["table4"], results2["table4"])
def diffSets(results1, results2):
@@ -95,20 +96,20 @@
s2 = set(results2)
d = s1 - s2
- print "\nIn first, not in second: (%d)" % (len(d),)
+ print("\nIn first, not in second: (%d)" % (len(d),))
for i in sorted(d):
- print i
+ print(i)
d = s2 - s1
- print "\nIn second, not in first: (%d)" % (len(d),)
+ print("\nIn second, not in first: (%d)" % (len(d),))
for i in sorted(d):
- print i
+ print(i)
def usage(error_msg=None):
if error_msg:
- print error_msg
+ print(error_msg)
- print """Usage: calverify_diff [options] FILE1 FILE2
+ print("""Usage: calverify_diff [options] FILE1 FILE2
Options:
-h Print this help and exit
@@ -119,7 +120,7 @@
Description:
This utility will analyze the output of two calverify runs
and show what is different between the two.
-"""
+""")
if error_msg:
raise ValueError(error_msg)
@@ -143,10 +144,10 @@
fname1 = args[0]
fname2 = args[1]
- print "*** CalVerify diff from %s to %s" % (
+ print("*** CalVerify diff from %s to %s" % (
os.path.basename(fname1),
os.path.basename(fname2),
- )
+ ))
results1 = analyze(fname1)
results2 = analyze(fname2)
diff(results1, results2)
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/changeip_calendar.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/changeip_calendar.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/changeip_calendar.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -9,7 +9,7 @@
# Software License Agreement accompanying the package this file is a
# part of. You may not port this file to another platform without
# Apple's written consent.
-
+from __future__ import print_function
from __future__ import with_statement
import os
@@ -21,15 +21,15 @@
def usage():
name = os.path.basename(sys.argv[0])
- print "Usage: %s [-hv] old-ip new-ip [old-hostname new-hostname]" % (name,)
- print " Options:"
- print " -h - print this message and exit"
- print " -v - print additional information when running"
- print " Arguments:"
- print " old-ip - current IPv4 address of the server"
- print " new-ip - new IPv4 address of the server"
- print " old-hostname - current FQDN for the server"
- print " new-hostname - new FQDN for the server"
+ print("Usage: %s [-hv] old-ip new-ip [old-hostname new-hostname]" % (name,))
+ print(" Options:")
+ print(" -h - print this message and exit")
+ print(" -v - print additional information when running")
+ print(" Arguments:")
+ print(" old-ip - current IPv4 address of the server")
+ print(" new-ip - new IPv4 address of the server")
+ print(" old-hostname - current FQDN for the server")
+ print(" new-hostname - new FQDN for the server")
def main():
@@ -38,7 +38,7 @@
# Since the serveradmin command must be run as root, so must this script
if os.getuid() != 0:
- print "%s must be run as root" % (name,)
+ print("%s must be run as root" % (name,))
sys.exit(1)
try:
@@ -74,15 +74,15 @@
oldHostname = newHostname = None
if verbose:
- print "Calendar Server: updating %s" % (configFile,)
+ print("Calendar Server: updating %s" % (configFile,))
try:
plist = readPlist(configFile)
except IOError:
- print "Error: could not open %s" % (configFile,)
+ print("Error: could not open %s" % (configFile,))
sys.exit(1)
except Exception, e:
- print "Error: could not parse %s" % (configFile,)
+ print("Error: could not parse %s" % (configFile,))
raise e
writePlist(plist, "%s.changeip.bak" % (configFile,))
@@ -91,7 +91,7 @@
writePlist(plist, configFile)
if verbose:
- print "Calendar Server: done"
+ print("Calendar Server: done")
def updatePlist(plist, oldIP, newIP, oldHostname, newHostname, verbose=False):
@@ -109,7 +109,7 @@
if oldHostname and newHostname:
newValue = newValue.replace(oldHostname, newHostname)
if verbose and value != newValue:
- print "Changed %s -> %s" % (value, newValue)
+ print("Changed %s -> %s" % (value, newValue))
return newValue
for keyPath in keys:
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/cmdline.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/cmdline.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/cmdline.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -30,7 +30,7 @@
# TODO: direct unit tests for these functions.
-def utilityMain(configFileName, serviceClass, reactor=None, serviceMaker=CalDAVServiceMaker, verbose=False):
+def utilityMain(configFileName, serviceClass, reactor=None, serviceMaker=CalDAVServiceMaker, patchConfig=None, onShutdown=None, verbose=False):
"""
Shared main-point for utilities.
@@ -52,6 +52,11 @@
provides L{ICalendarStore} and/or L{IAddressbookStore} and returns an
L{IService}.
+ @param patchConfig: a 1-argument callable which takes a config object
+ and makes and changes necessary for the tool.
+
+ @param onShutdown: a 0-argument callable which will run on shutdown.
+
@param reactor: if specified, the L{IReactorTime} / L{IReactorThreads} /
L{IReactorTCP} (etc) provider to use. If C{None}, the default reactor
will be imported and used.
@@ -66,6 +71,8 @@
from twisted.internet import reactor
try:
config = loadConfig(configFileName)
+ if patchConfig is not None:
+ patchConfig(config)
# If we don't have permission to access the DataRoot directory, we
# can't proceed. If this fails it should raise OSError which we
@@ -83,6 +90,8 @@
reactor.addSystemEventTrigger("during", "startup", service.startService)
reactor.addSystemEventTrigger("before", "shutdown", service.stopService)
+ if onShutdown is not None:
+ reactor.addSystemEventTrigger("before", "shutdown", onShutdown)
except (ConfigurationError, OSError), e:
sys.stderr.write("Error: %s\n" % (e,))
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/config.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/config.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/config.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,6 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
"""
This tool reads the Calendar Server configuration file and emits the
@@ -31,16 +32,16 @@
def usage(e=None):
if e:
- print e
- print ""
+ print(e)
+ print("")
name = os.path.basename(sys.argv[0])
- print "usage: %s [options] config_key" % (name,)
- print ""
- print "Print the value of the given config key."
- print "options:"
- print " -h --help: print this help and exit"
- print " -f --config: Specify caldavd.plist configuration path"
+ print("usage: %s [options] config_key" % (name,))
+ print("")
+ print("Print the value of the given config key.")
+ print("options:")
+ print(" -h --help: print this help and exit")
+ print(" -f --config: Specify caldavd.plist configuration path")
if e:
sys.exit(64)
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/dbinspect.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/dbinspect.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/dbinspect.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,6 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
"""
This tool allows data in the database to be directly inspected using a set
@@ -49,8 +50,8 @@
def usage(e=None):
if e:
- print e
- print ""
+ print(e)
+ print("")
try:
DBInspectOptions().opt_help()
except SystemExit:
@@ -152,8 +153,8 @@
count,
))
- print "\n"
- print "Database Tables (total=%d):\n" % (len(results),)
+ print("\n")
+ print("Database Tables (total=%d):\n" % (len(results),))
table.printTable()
@@ -189,8 +190,8 @@
shortname,
))
- print "\n"
- print "Calendar Homes (total=%d, missing=%d):\n" % (len(uids), missing,)
+ print("\n")
+ print("Calendar Homes (total=%d, missing=%d):\n" % (len(uids), missing,))
table.printTable()
@@ -245,8 +246,8 @@
"%.2f" % ((1.0 * totals[2]) / totals[0] if totals[0] else 0,),
))
- print "\n"
- print "Calendars with resource count (total=%d):\n" % (len(results),)
+ print("\n")
+ print("Calendars with resource count (total=%d):\n" % (len(results),))
table.printTable()
@@ -292,8 +293,8 @@
count
))
- print "\n"
- print "Calendars with resource count (total=%d):\n" % (len(uids),)
+ print("\n")
+ print("Calendars with resource count (total=%d):\n" % (len(uids),))
table.printTable()
@@ -346,8 +347,8 @@
totals[1] += count
table.addFooter(("Total", "", totals[0], "", totals[1]))
- print "\n"
- print "Calendars with resource count (total=%d):\n" % (len(uids),)
+ print("\n")
+ print("Calendars with resource count (total=%d):\n" % (len(uids),))
table.printTable()
@@ -397,8 +398,8 @@
caluid
))
- print "\n"
- print "Calendar events (total=%d):\n" % (len(uids),)
+ print("\n")
+ print("Calendar events (total=%d):\n" % (len(uids),))
table.printTable()
@@ -435,7 +436,7 @@
try:
int(rid)
except ValueError:
- print 'Resource ID must be an integer'
+ print('Resource ID must be an integer')
returnValue(None)
uids = yield self.getEvents(txn, rid)
@@ -450,8 +451,8 @@
rid,
))
- print "\n"
- print "Calendar events (total=%d):\n" % (len(uids),)
+ print("\n")
+ print("Calendar events (total=%d):\n" % (len(uids),))
table.printTable()
@@ -492,9 +493,9 @@
table.addRow(("Resource ID:", resource_id))
table.addRow(("Created", created))
table.addRow(("Modified", modified))
- print "\n"
+ print("\n")
table.printTable()
- print data
+ print(data)
@inlineCallbacks
@@ -533,13 +534,13 @@
try:
int(rid)
except ValueError:
- print 'Resource ID must be an integer'
+ print('Resource ID must be an integer')
returnValue(None)
result = yield self.getData(txn, rid)
if result:
self.printEventDetails(txn, result[0])
else:
- print "Could not find resource"
+ print("Could not find resource")
def getData(self, txn, rid):
@@ -561,7 +562,7 @@
for result in rows:
self.printEventDetails(txn, result)
else:
- print "Could not find icalendar data"
+ print("Could not find icalendar data")
def getData(self, txn, uid):
@@ -583,7 +584,7 @@
for result in rows:
self.printEventDetails(txn, result)
else:
- print "Could not find icalendar data"
+ print("Could not find icalendar data")
def getData(self, txn, name):
@@ -606,7 +607,7 @@
for result in rows:
self.printEventDetails(txn, result)
else:
- print "Could not find icalendar data"
+ print("Could not find icalendar data")
def getData(self, txn, uid):
@@ -630,7 +631,7 @@
for result in rows:
self.printEventDetails(txn, result)
else:
- print "Could not find icalendar data"
+ print("Could not find icalendar data")
def getData(self, txn, uid, name):
@@ -650,7 +651,7 @@
path = raw_input("Path: ")
pathbits = path.split("/")
if len(pathbits) != 6:
- print "Not a valid calendar object resource path"
+ print("Not a valid calendar object resource path")
returnValue(None)
homeName = pathbits[3]
calendarName = pathbits[4]
@@ -660,7 +661,7 @@
for result in rows:
self.printEventDetails(txn, result)
else:
- print "Could not find icalendar data"
+ print("Could not find icalendar data")
def getData(self, txn, homeName, calendarName, resourceName):
@@ -692,7 +693,7 @@
for result in rows:
self.printEventDetails(txn, result)
else:
- print "Could not find icalendar data"
+ print("Could not find icalendar data")
def getData(self, txn, text):
@@ -719,18 +720,18 @@
try:
start = PyCalendarDateTime.parseText(start)
except ValueError:
- print "Invalid start value"
+ print("Invalid start value")
returnValue(None)
try:
end = PyCalendarDateTime.parseText(end)
except ValueError:
- print "Invalid end value"
+ print("Invalid end value")
returnValue(None)
timerange = caldavxml.TimeRange(start=start.getText(), end=end.getText())
home = yield txn.calendarHomeWithUID(uid)
if home is None:
- print "Could not find calendar home"
+ print("Could not find calendar home")
returnValue(None)
yield self.eventsForEachCalendar(home, uid, timerange)
@@ -777,9 +778,9 @@
table.addRow(("Resource ID:", event._resourceID))
table.addRow(("Created", event.created()))
table.addRow(("Modified", event.modified()))
- print "\n"
+ print("\n")
table.printTable()
- print ical_data.getTextWithTimezones(includeTimezones=False)
+ print(ical_data.getTextWithTimezones(includeTimezones=False))
@@ -791,7 +792,7 @@
def doIt(self, txn):
if raw_input("Do you really want to remove all data [y/n]: ")[0].lower() != 'y':
- print "No data removed"
+ print("No data removed")
returnValue(None)
wipeout = (
@@ -827,21 +828,21 @@
for tableschema in wipeout:
yield self.removeTableData(txn, tableschema)
- print "Removed rows in table %s" % (tableschema,)
+ print("Removed rows in table %s" % (tableschema,))
if calendaruserproxy.ProxyDBService is not None:
calendaruserproxy.ProxyDBService.clean() #@UndefinedVariable
- print "Removed all proxies"
+ print("Removed all proxies")
else:
- print "No proxy database to clean."
+ print("No proxy database to clean.")
fp = FilePath(config.AttachmentsRoot)
if fp.exists():
for child in fp.children():
child.remove()
- print "Removed attachments."
+ print("Removed attachments.")
else:
- print "No attachments path to delete."
+ print("No attachments path to delete.")
@inlineCallbacks
@@ -904,7 +905,7 @@
try:
yield self.runCommandByName(self.commands[position])
except IndexError:
- print "Position %d not available" % (position,)
+ print("Position %d not available" % (position,))
returnValue(None)
@@ -913,7 +914,7 @@
try:
yield self.runCommand(self.commandMap[name])
except IndexError:
- print "Unknown command: '%s'" % (name,)
+ print("Unknown command: '%s'" % (name,))
@inlineCallbacks
@@ -925,18 +926,18 @@
yield txn.commit()
except Exception, e:
traceback.print_exc()
- print "Command '%s' failed because of: %s" % (cmd.name(), e,)
+ print("Command '%s' failed because of: %s" % (cmd.name(), e,))
yield txn.abort()
def printCommands(self):
- print "\n<---- Commands ---->"
+ print("\n<---- Commands ---->")
for ctr, name in enumerate(self.commands):
- print "%d. %s" % (ctr + 1, name,)
+ print("%d. %s" % (ctr + 1, name,))
if self.options["purging"]:
- print "P. Purge\n"
- print "Q. Quit\n"
+ print("P. Purge\n")
+ print("Q. Quit\n")
@inlineCallbacks
@@ -956,7 +957,7 @@
try:
position = int(cmd)
except ValueError:
- print "Invalid command. Try again.\n"
+ print("Invalid command. Try again.\n")
continue
yield self.runCommandByPosition(position - 1)
@@ -975,7 +976,7 @@
try:
calendaruserproxy.ProxyDBService = proxydbClass(**config.ProxyDBService.params)
except IOError:
- print "Could not start proxydb service"
+ print("Could not start proxydb service")
return self._directory
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/dkimtool.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/dkimtool.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/dkimtool.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -41,7 +41,7 @@
if options["key"]:
open(options["key"], "w").write(output)
else:
- print output
+ print(output)
lineBreak = True
output = key.publickey().exportKey()
@@ -50,7 +50,7 @@
else:
if lineBreak:
print
- print output
+ print(output)
lineBreak = True
if options["txt"]:
@@ -58,7 +58,7 @@
txt = "v=DKIM1; p=%s" % (output,)
if lineBreak:
print
- print txt
+ print(txt)
@@ -105,7 +105,7 @@
s = StringIO()
_writeRequest(dkim, s)
- print s.getvalue()
+ print(s.getvalue())
@@ -131,9 +131,9 @@
try:
yield dkim.verify()
except DKIMVerificationError, e:
- print "Verification Failed: %s" % (e,)
+ print("Verification Failed: %s" % (e,))
else:
- print "Verification Succeeded"
+ print("Verification Succeeded")
@@ -192,8 +192,8 @@
def usage(e=None):
if e:
- print e
- print ""
+ print(e)
+ print("")
try:
DKIMToolOptions().opt_help()
except SystemExit:
@@ -282,7 +282,7 @@
try:
yield fn(options)
except Exception, e:
- print e
+ print(e)
finally:
reactor.stop()
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/doublequotefix.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/doublequotefix.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/doublequotefix.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,6 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import datetime
import getopt
@@ -32,21 +33,21 @@
def usage(e=None):
if e:
- print e
- print ""
+ print(e)
+ print("")
name = os.path.basename(sys.argv[0])
- print "usage: %s [options]" % (name,)
- print ""
- print "Fix double-quote/escape bugs in iCalendar data."
- print ""
- print "options:"
- print " -h --help: print this help and exit"
- print " -p <path>: path to calendar server document root [icalserver default]"
- print " -u <path>: path to file containing uris to process [uris.txt]"
- print " --fix: Apply fixes, otherwise only check for problems"
- print ""
- print "uris: list of uris to process"
+ print("usage: %s [options]" % (name,))
+ print("")
+ print("Fix double-quote/escape bugs in iCalendar data.")
+ print("")
+ print("options:")
+ print(" -h --help: print this help and exit")
+ print(" -p <path>: path to calendar server document root [icalserver default]")
+ print(" -u <path>: path to file containing uris to process [uris.txt]")
+ print(" --fix: Apply fixes, otherwise only check for problems")
+ print("")
+ print("uris: list of uris to process")
if e:
sys.exit(64)
@@ -76,7 +77,7 @@
# Verify we have a valid path
pathBits = uri.strip("/").rstrip("/").split("/")
if len(pathBits) != 4 or pathBits[0] != "calendars" or pathBits[1] != "__uids__":
- print "Invalid uri (ignoring): %s" % (uri,)
+ print("Invalid uri (ignoring): %s" % (uri,))
totalErrors += 1
return
@@ -92,7 +93,7 @@
)
if not os.path.exists(calendarPath):
- print "Calendar path does not exist: %s" % (calendarPath,)
+ print("Calendar path does not exist: %s" % (calendarPath,))
totalErrors += 1
return
@@ -109,7 +110,7 @@
f = open(icsPath)
icsData = f.read()
except Exception, e:
- print "Failed to read file %s due to %s" % (icsPath, str(e),)
+ print("Failed to read file %s due to %s" % (icsPath, str(e),))
totalErrors += 1
continue
finally:
@@ -131,7 +132,7 @@
f = open(icsPath, "w")
f.write(icsData)
except Exception, e:
- print "Failed to write file %s due to %s" % (icsPath, str(e),)
+ print("Failed to write file %s due to %s" % (icsPath, str(e),))
totalErrors += 1
continue
finally:
@@ -140,9 +141,9 @@
# Change ETag on written resource
updateEtag(icsPath, icsData)
didFix = True
- print "Problem fixed in: <BasePath>%s" % (icsPath[basePathLength:],)
+ print("Problem fixed in: <BasePath>%s" % (icsPath[basePathLength:],))
else:
- print "Problem found in: <BasePath>%s" % (icsPath[basePathLength:],)
+ print("Problem found in: <BasePath>%s" % (icsPath[basePathLength:],))
totalProblems += 1
# Change CTag on calendar collection if any resource was written
@@ -182,24 +183,24 @@
for line in f:
pos = line.find("/calendars/")
if pos == -1:
- print "Ignored log line: %s" % (line,)
+ print("Ignored log line: %s" % (line,))
continue
uris.add(line[pos:].split()[0])
uris = list(uris)
uris.sort()
f.close()
- print "Base Path is: %s" % (basePath,)
- print "Number of unique URIs to fix: %d" % (len(uris),)
- print ""
+ print("Base Path is: %s" % (basePath,))
+ print("Number of unique URIs to fix: %d" % (len(uris),))
+ print("")
for uri in uris:
scanURI(uri, basePath, doFix)
- print ""
- print "---------------------"
- print "Total Problems %s: %d of %d" % ("Fixed" if doFix else "Found", totalProblems, totalScanned,)
+ print("")
+ print("---------------------")
+ print("Total Problems %s: %d of %d" % ("Fixed" if doFix else "Found", totalProblems, totalScanned,))
if totalErrors:
- print "Total Errors: %s" % (totalErrors,)
+ print("Total Errors: %s" % (totalErrors,))
if __name__ == '__main__':
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/export.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/export.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/export.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -33,6 +33,8 @@
per-user data such as alarms.
"""
+from __future__ import print_function
+
import os
import sys
import itertools
@@ -52,8 +54,8 @@
def usage(e=None):
if e:
- print e
- print ""
+ print(e)
+ print("")
try:
ExportOptions().opt_help()
except SystemExit:
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/fixcalendardata.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/fixcalendardata.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/fixcalendardata.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,6 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import re
import datetime
@@ -38,24 +39,24 @@
def usage(e=None):
if e:
- print e
- print ""
+ print(e)
+ print("")
name = os.path.basename(sys.argv[0])
- print "usage: %s [options]" % (name,)
- print ""
- print "Fix double-quote/escape bugs in iCalendar data."
- print "Fix incorrect use of TZID in iCalendar data."
- print ""
- print "options:"
- print " -h --help: print this help and exit"
- print " -f --config: Specify caldavd.plist configuration path"
- print " -o <path>: path to file for scan results [problems.txt]"
- print " -v: print each calendar home scanned"
- print " --scan: Scan for problems"
- print " --fix: Apply fixes"
- print ""
- print "One of --scan or --fix must be specified. Both may be specified"
+ print("usage: %s [options]" % (name,))
+ print("")
+ print("Fix double-quote/escape bugs in iCalendar data.")
+ print("Fix incorrect use of TZID in iCalendar data.")
+ print("")
+ print("options:")
+ print(" -h --help: print this help and exit")
+ print(" -f --config: Specify caldavd.plist configuration path")
+ print(" -o <path>: path to file for scan results [problems.txt]")
+ print(" -v: print each calendar home scanned")
+ print(" --scan: Scan for problems")
+ print(" --fix: Apply fixes")
+ print("")
+ print("One of --scan or --fix must be specified. Both may be specified")
if e:
sys.exit(64)
@@ -101,7 +102,7 @@
def scanCalendarHome(basePath, calendarHome, scanFile, doFix):
if verbose:
- print "Scanning: %s" % (calendarHome,)
+ print("Scanning: %s" % (calendarHome,))
for item in os.listdir(calendarHome):
calendarPath = os.path.join(calendarHome, item)
@@ -116,7 +117,7 @@
global totalScanned
if not os.path.exists(calendarPath):
- print "Calendar path does not exist: %s" % (calendarPath,)
+ print("Calendar path does not exist: %s" % (calendarPath,))
totalErrors += 1
return
@@ -134,7 +135,7 @@
f = open(icsPath)
icsData = f.read()
except Exception, e:
- print "Failed to read file %s due to %s" % (icsPath, str(e),)
+ print("Failed to read file %s due to %s" % (icsPath, str(e),))
totalErrors += 1
continue
finally:
@@ -158,9 +159,9 @@
if doFix:
if fixPath(icsPath, icsData, fixQuotes, fixTZIDs, fixMultiVALARMs):
didFix = True
- print "Problems %s fixed in: <BasePath>%s" % (",".join(problems), icsPath[basePathLength:],)
+ print("Problems %s fixed in: <BasePath>%s" % (",".join(problems), icsPath[basePathLength:],))
else:
- print "Problem %s found in: <BasePath>%s" % (",".join(problems), icsPath[basePathLength:],)
+ print("Problem %s found in: <BasePath>%s" % (",".join(problems), icsPath[basePathLength:],))
scanFile.write(icsPath + "\n")
totalProblems += 1
@@ -220,7 +221,7 @@
f = open(scanPath)
lines = [line[:-1] for line in f]
except Exception, e:
- print "Failed to read file %s due to %s" % (scanPath, str(e),)
+ print("Failed to read file %s due to %s" % (scanPath, str(e),))
totalErrors += 1
return
finally:
@@ -241,7 +242,7 @@
icsPath = os.path.join(calendarPath, icsName)
if fixPath(icsPath):
didFix = True
- print "Problem fixed in: <BasePath>%s" % (icsPath[basePathLength:],)
+ print("Problem fixed in: <BasePath>%s" % (icsPath[basePathLength:],))
totalProblems += 1
# Change CTag on calendar collection if any resource was written
@@ -260,7 +261,7 @@
f = open(icsPath)
icsData = f.read()
except Exception, e:
- print "Failed to read file %s due to %s" % (icsPath, str(e),)
+ print("Failed to read file %s due to %s" % (icsPath, str(e),))
totalErrors += 1
return False
finally:
@@ -302,7 +303,7 @@
f = open(icsPath, "w")
f.write(icsData)
except Exception, e:
- print "Failed to write file %s due to %s" % (icsPath, str(e),)
+ print("Failed to write file %s due to %s" % (icsPath, str(e),))
totalErrors += 1
return False
finally:
@@ -348,29 +349,29 @@
basePath = parsePlist(plistPath)
start = time.time()
- print "Base Path is: %s" % (basePath,)
+ print("Base Path is: %s" % (basePath,))
if doScan:
if doFix:
- print "Scanning data store and fixing"
+ print("Scanning data store and fixing")
scanFile = None
else:
- print "Scanning data store and writing results to '%s'" % (scanPath,)
+ print("Scanning data store and writing results to '%s'" % (scanPath,))
try:
scanFile = open(scanPath, "w")
except Exception, e:
- print "Failed to open file for writing %s due to %s" % (scanPath, str(e),)
+ print("Failed to open file for writing %s due to %s" % (scanPath, str(e),))
scanData(basePath, scanFile, doFix)
elif doFix:
- print "Fixing data using results from '%s'" % (scanPath,)
+ print("Fixing data using results from '%s'" % (scanPath,))
fixData(basePath, scanPath)
difftime = time.time() - start
- print ""
- print "---------------------"
- print "Total Problems %s: %d of %d" % ("Fixed" if doFix else "Found", totalProblems, totalScanned,)
+ print("")
+ print("---------------------")
+ print("Total Problems %s: %d of %d" % ("Fixed" if doFix else "Found", totalProblems, totalScanned,))
if totalErrors:
- print "Total Errors: %s" % (totalErrors,)
- print "Time taken (secs): %.1f" % (difftime,)
+ print("Total Errors: %s" % (totalErrors,))
+ print("Time taken (secs): %.1f" % (difftime,))
if __name__ == '__main__':
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/gateway.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/gateway.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/gateway.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,6 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
from getopt import getopt, GetoptError
import os
@@ -40,15 +41,15 @@
def usage(e=None):
name = os.path.basename(sys.argv[0])
- print "usage: %s [options]" % (name,)
- print ""
- print " TODO: describe usage"
- print ""
- print "options:"
- print " -h --help: print this help and exit"
- print " -e --error: send stderr to stdout"
- print " -f --config <path>: Specify caldavd.plist configuration path"
- print ""
+ print("usage: %s [options]" % (name,))
+ print("")
+ print(" TODO: describe usage")
+ print("")
+ print("options:")
+ print(" -h --help: print this help and exit")
+ print(" -e --error: send stderr to stdout")
+ print(" -f --config <path>: Specify caldavd.plist configuration path")
+ print("")
if e:
sys.exit(64)
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/icalsplit.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/icalsplit.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/icalsplit.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import os
import sys
@@ -53,7 +54,7 @@
uid = subcalendar.resourceUID()
subFileName = os.path.join(outputDirectory, uid + ".ics")
- print "Writing %s" % (subFileName,)
+ print("Writing %s" % (subFileName,))
subcalendar_file = file(subFileName, "w")
try:
@@ -64,19 +65,19 @@
def usage(e=None):
if e:
- print e
- print ""
+ print(e)
+ print("")
name = os.path.basename(sys.argv[0])
- print "usage: %s [options] input_file output_directory" % (name,)
- print ""
- print " Splits up monolithic iCalendar data into separate files for each"
- print " subcomponent so as to comply with CalDAV requirements for"
- print " individual resources."
- print ""
- print "options:"
- print " -h --help: print this help and exit"
- print ""
+ print("usage: %s [options] input_file output_directory" % (name,))
+ print("")
+ print(" Splits up monolithic iCalendar data into separate files for each")
+ print(" subcomponent so as to comply with CalDAV requirements for")
+ print(" individual resources.")
+ print("")
+ print("options:")
+ print(" -h --help: print this help and exit")
+ print("")
if e:
sys.exit(64)
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/loadaugmentdb.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/loadaugmentdb.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/loadaugmentdb.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
from calendarserver.tools.managetimezones import StandardIOObserver
from calendarserver.tools.util import loadConfig, getDirectory, \
@@ -43,20 +44,20 @@
def usage(e=None):
if e:
- print e
- print ""
+ print(e)
+ print("")
name = os.path.basename(sys.argv[0])
- print "usage: %s [options]" % (name,)
- print ""
- print "Populate an sqlite or PostgreSQL augments database with values"
- print "from an XML augments file."
- print ""
- print "options:"
- print " -h --help: print this help and exit"
- print " -f --config: Specify caldavd.plist configuration path"
- print " -x --xmlfile: Specify xml augments file path"
- print " -r --remove: Remove all entries from the database"
+ print("usage: %s [options]" % (name,))
+ print("")
+ print("Populate an sqlite or PostgreSQL augments database with values")
+ print("from an XML augments file.")
+ print("")
+ print("options:")
+ print(" -h --help: print this help and exit")
+ print(" -f --config: Specify caldavd.plist configuration path")
+ print(" -x --xmlfile: Specify xml augments file path")
+ print(" -r --remove: Remove all entries from the database")
if e:
sys.exit(64)
@@ -160,10 +161,10 @@
yield augment.AugmentService.removeAugmentRecords(remove_uids)
removed = len(remove_uids)
- print "Changes:"
- print " Added: %d" % (added,)
- print " Changed: %d" % (updated,)
- print " Removed: %d" % (removed,)
+ print("Changes:")
+ print(" Added: %d" % (added,))
+ print(" Changed: %d" % (updated,))
+ print(" Removed: %d" % (removed,))
finally:
#
# Stop the reactor
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/managepostgres.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/managepostgres.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/managepostgres.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
from optparse import OptionParser
import os
@@ -22,11 +23,11 @@
import time
def error(s):
- print s
+ print(s)
sys.exit(1)
def cmd(s):
- print s
+ print(s)
subprocess.call(s, shell=True)
def doInit(basedir):
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/managetimezones.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/managetimezones.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/managetimezones.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
from pycalendar.calendar import PyCalendar
from pycalendar.datetime import PyCalendarDateTime
@@ -65,20 +66,20 @@
Refresh data from IANA.
"""
- print "Downloading latest data from IANA"
+ print("Downloading latest data from IANA")
if tzvers:
path = "http://www.iana.org/time-zones/repository/releases/tzdata%s.tar.gz" % (tzvers,)
else:
path = "http://www.iana.org/time-zones/repository/tzdata-latest.tar.gz"
tzvers = "Latest (%s)" % (PyCalendarDateTime.getToday().getText(),)
data = urllib.urlretrieve(path)
- print "Extract data at: %s" % (data[0])
+ print("Extract data at: %s" % (data[0]))
rootdir = tempfile.mkdtemp()
zonedir = os.path.join(rootdir, "tzdata")
os.mkdir(zonedir)
with tarfile.open(data[0], "r:gz") as t:
t.extractall(zonedir)
- print "Converting data at: %s" % (zonedir,)
+ print("Converting data at: %s" % (zonedir,))
startYear = 1800
endYear = PyCalendarDateTime.getToday().getYear() + 10
PyCalendar.sProdID = "-//calendarserver.org//Zonal//EN"
@@ -88,22 +89,22 @@
parser.parse(os.path.join(zonedir, file))
parser.generateZoneinfoFiles(os.path.join(rootdir, "zoneinfo"), startYear, endYear, filterzones=())
- print "Copy new zoneinfo to destination: %s" % (tzpath,)
+ print("Copy new zoneinfo to destination: %s" % (tzpath,))
z = FilePath(os.path.join(rootdir, "zoneinfo"))
tz = FilePath(tzpath)
z.copyTo(tz)
- print "Updating XML file at: %s" % (xmlfile,)
+ print("Updating XML file at: %s" % (xmlfile,))
tzdb.readDatabase()
tzdb.updateDatabase()
- print "Current total: %d" % (len(tzdb.timezones),)
- print "Total Changed: %d" % (tzdb.changeCount,)
+ print("Current total: %d" % (len(tzdb.timezones),))
+ print("Total Changed: %d" % (tzdb.changeCount,))
if tzdb.changeCount:
- print "Changed:"
+ print("Changed:")
for k in sorted(tzdb.changed):
- print " %s" % (k,)
+ print(" %s" % (k,))
versfile = os.path.join(os.path.dirname(xmlfile), "version.txt")
- print "Updating version file at: %s" % (versfile,)
+ print("Updating version file at: %s" % (versfile,))
with open(versfile, "w") as f:
f.write("Olson data source: %s\n" % (tzvers,))
@@ -114,9 +115,9 @@
Create new xml file.
"""
- print "Creating new XML file at: %s" % (xmlfile,)
+ print("Creating new XML file at: %s" % (xmlfile,))
tzdb.createNewDatabase()
- print "Current total: %d" % (len(tzdb.timezones),)
+ print("Current total: %d" % (len(tzdb.timezones),))
@@ -125,15 +126,15 @@
Update xml file.
"""
- print "Updating XML file at: %s" % (xmlfile,)
+ print("Updating XML file at: %s" % (xmlfile,))
tzdb.readDatabase()
tzdb.updateDatabase()
- print "Current total: %d" % (len(tzdb.timezones),)
- print "Total Changed: %d" % (tzdb.changeCount,)
+ print("Current total: %d" % (len(tzdb.timezones),))
+ print("Total Changed: %d" % (tzdb.changeCount,))
if tzdb.changeCount:
- print "Changed:"
+ print("Changed:")
for k in sorted(tzdb.changed):
- print " %s" % (k,)
+ print(" %s" % (k,))
@@ -142,12 +143,12 @@
List current timezones from xml file.
"""
- print "Listing XML file at: %s" % (xmlfile,)
+ print("Listing XML file at: %s" % (xmlfile,))
tzdb.readDatabase()
- print "Current timestamp: %s" % (tzdb.dtstamp,)
- print "Timezones:"
+ print("Current timestamp: %s" % (tzdb.dtstamp,))
+ print("Timezones:")
for k in sorted(tzdb.timezones.keys()):
- print " %s" % (k,)
+ print(" %s" % (k,))
@@ -156,16 +157,16 @@
Check for local timezone changes.
"""
- print "Changes from XML file at: %s" % (xmlfile,)
+ print("Changes from XML file at: %s" % (xmlfile,))
tzdb.readDatabase()
- print "Check timestamp: %s" % (changed,)
- print "Current timestamp: %s" % (tzdb.dtstamp,)
+ print("Check timestamp: %s" % (changed,))
+ print("Current timestamp: %s" % (tzdb.dtstamp,))
results = [k for k, v in tzdb.timezones.items() if v.dtstamp > changed]
- print "Total Changed: %d" % (len(results),)
+ print("Total Changed: %d" % (len(results),))
if results:
- print "Changed:"
+ print("Changed:")
for k in sorted(results):
- print " %s" % (k,)
+ print(" %s" % (k,))
@@ -174,11 +175,11 @@
try:
new, changed = yield tzdb.syncWithServer()
- print "New: %d" % (new,)
- print "Changed: %d" % (changed,)
- print "Current total: %d" % (len(tzdb.timezones),)
+ print("New: %d" % (new,))
+ print("Changed: %d" % (changed,))
+ print("Current total: %d" % (len(tzdb.timezones),))
except Exception, e:
- print "Could not sync with server: %s" % (str(e),)
+ print("Could not sync with server: %s" % (str(e),))
finally:
reactor.stop()
@@ -192,7 +193,7 @@
except:
pass
if action == "cache":
- print "Caching from secondary server: %s" % (url,)
+ print("Caching from secondary server: %s" % (url,))
observer = StandardIOObserver()
observer.start()
@@ -205,10 +206,10 @@
def usage(error_msg=None):
if error_msg:
- print error_msg
- print
+ print(error_msg)
+ print("")
- print """Usage: managetimezones [options]
+ print("""Usage: managetimezones [options]
Options:
-h Print this help and exit
-f XML file path
@@ -232,7 +233,7 @@
This utility will create, update or list an XML timezone database
summary file, or refresh iCalendar timezone from IANA (Olson).
-"""
+""")
if error_msg:
raise ValueError(error_msg)
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/migrate.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/migrate.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/migrate.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,6 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
"""
This tool migrates existing calendar data from any previous calendar server
@@ -36,17 +37,17 @@
def usage(e=None):
if e:
- print e
- print ""
+ print(e)
+ print("")
name = os.path.basename(sys.argv[0])
- print "usage: %s [options]" % (name,)
- print ""
- print "Migrate calendar data to current version"
- print __doc__
- print "options:"
- print " -h --help: print this help and exit"
- print " -f --config: Specify caldavd.plist configuration path"
+ print("usage: %s [options]" % (name,))
+ print("")
+ print("Migrate calendar data to current version")
+ print(__doc__)
+ print("options:")
+ print(" -h --help: print this help and exit")
+ print(" -f --config: Specify caldavd.plist configuration path")
if e:
sys.exit(64)
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/migrate_verify.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/migrate_verify.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/migrate_verify.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,6 +15,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
+
from txdav.common.datastore.sql_tables import schema, _BIND_MODE_OWN
from twext.enterprise.dal.syntax import Select, Parameter
@@ -38,8 +40,8 @@
def usage(e=None):
if e:
- print e
- print ""
+ print(e)
+ print("")
try:
MigrateVerifyOptions().opt_help()
except SystemExit:
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/notifications.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/notifications.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/notifications.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
from calendarserver.tools.util import loadConfig
from datetime import datetime
@@ -42,26 +43,26 @@
def usage(e=None):
name = os.path.basename(sys.argv[0])
- print "usage: %s [options] username" % (name,)
- print ""
- print " Monitor push notification events from calendar server"
- print ""
- print "options:"
- print " -a --admin <username>: Specify an administrator username"
- print " -f --config <path>: Specify caldavd.plist configuration path"
- print " -h --help: print this help and exit"
- print " -H --host <hostname>: calendar server host name"
- print " -n --node <pubsub node>: pubsub node to subscribe to *"
- print " -p --port <port number>: calendar server port number"
- print " -s --ssl: use https (default is http)"
- print " -v --verbose: print additional information including XMPP traffic"
- print ""
- print " * The --node option is only required for calendar servers that"
- print " don't advertise the push-transports DAV property (such as a Snow"
- print " Leopard server). In this case, --host should specify the name"
- print " of the XMPP server and --port should specify the port XMPP is"
- print " is listening on."
- print ""
+ print("usage: %s [options] username" % (name,))
+ print("")
+ print(" Monitor push notification events from calendar server")
+ print("")
+ print("options:")
+ print(" -a --admin <username>: Specify an administrator username")
+ print(" -f --config <path>: Specify caldavd.plist configuration path")
+ print(" -h --help: print this help and exit")
+ print(" -H --host <hostname>: calendar server host name")
+ print(" -n --node <pubsub node>: pubsub node to subscribe to *")
+ print(" -p --port <port number>: calendar server port number")
+ print(" -s --ssl: use https (default is http)")
+ print(" -v --verbose: print additional information including XMPP traffic")
+ print("")
+ print(" * The --node option is only required for calendar servers that")
+ print(" don't advertise the push-transports DAV property (such as a Snow")
+ print(" Leopard server). In this case, --host should specify the name")
+ print(" of the XMPP server and --port should specify the port XMPP is")
+ print(" is listening on.")
+ print("")
if e:
sys.stderr.write("%s\n" % (e,))
@@ -125,7 +126,7 @@
try:
loadConfig(configFileName)
except ConfigurationError, e:
- print "Error in configuration: %s" % (e,)
+ print("Error in configuration: %s" % (e,))
sys.exit(1)
useSSL = config.EnableSSL
@@ -168,7 +169,7 @@
self.verbose = verbose
if self.verbose:
- print "JID:", self.jid, "Pubsub service:", self.service
+ print("JID:", self.jid, "Pubsub service:", self.service)
self.presenceSeconds = 60
self.presenceCall = None
@@ -193,7 +194,7 @@
@inlineCallbacks
def sigint_handler(self, num, frame):
- print " Shutting down..."
+ print(" Shutting down...")
yield self.unsubscribeAll()
reactor.stop()
@@ -206,7 +207,7 @@
def connected(self, xmlStream):
self.xmlStream = xmlStream
if self.verbose:
- print "XMPP connection successful"
+ print("XMPP connection successful")
xmlStream.rawDataInFn = self.rawDataIn
xmlStream.rawDataOutFn = self.rawDataOut
xmlStream.addObserver("/message/event/items",
@@ -218,25 +219,25 @@
self.presenceCall.cancel()
self.presenceCall = None
if self.verbose:
- print "XMPP disconnected"
+ print("XMPP disconnected")
def initFailed(self, failure):
self.xmlStream = None
- print "XMPP connection failure: %s" % (failure,)
+ print("XMPP connection failure: %s" % (failure,))
reactor.stop()
@inlineCallbacks
def authenticated(self, xmlStream):
if self.verbose:
- print "XMPP authentication successful"
+ print("XMPP authentication successful")
self.sendPresence()
for node, (url, name, kind) in self.nodes.iteritems():
yield self.subscribe(node, name, kind)
- print "Awaiting notifications (hit Control-C to end)"
+ print("Awaiting notifications (hit Control-C to end)")
def authFailed(self, e):
- print "XMPP authentication failed"
+ print("XMPP authentication failed")
reactor.stop()
def sendPresence(self):
@@ -254,10 +255,10 @@
node = str(node)
url, name, kind = self.nodes.get(node, ("Not subscribed", "Unknown", "Unknown"))
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
- print '%s | Notification for "%s" (%s)' % (timestamp, name, kind)
+ print('%s | Notification for "%s" (%s)' % (timestamp, name, kind))
if self.verbose:
- print " node = %s" % (node,)
- print " url = %s" % (url,)
+ print(" node = %s" % (node,))
+ print(" url = %s" % (url,))
@inlineCallbacks
@@ -267,14 +268,14 @@
subElement = pubsubElement.addElement("subscribe")
subElement["node"] = node
subElement["jid"] = self.jid
- print 'Subscribing to "%s" (%s)' % (name, kind)
+ print('Subscribing to "%s" (%s)' % (name, kind))
if self.verbose:
- print node
+ print(node)
try:
yield iq.send(to=self.service)
- print "OK"
+ print("OK")
except Exception, e:
- print "Subscription failure: %s %s" % (node, e)
+ print("Subscription failure: %s %s" % (node, e))
@inlineCallbacks
def unsubscribe(self, node, name, kind):
@@ -283,14 +284,14 @@
subElement = pubsubElement.addElement("unsubscribe")
subElement["node"] = node
subElement["jid"] = self.jid
- print 'Unsubscribing from "%s" (%s)' % (name, kind)
+ print('Unsubscribing from "%s" (%s)' % (name, kind))
if self.verbose:
- print node
+ print(node)
try:
yield iq.send(to=self.service)
- print "OK"
+ print("OK")
except Exception, e:
- print "Unsubscription failure: %s %s" % (node, e)
+ print("Unsubscription failure: %s %s" % (node, e))
@inlineCallbacks
@@ -299,18 +300,18 @@
iq = IQ(self.xmlStream)
pubsubElement = iq.addElement("pubsub", defaultUri=self.pubsubNS)
pubsubElement.addElement("subscriptions")
- print "Requesting list of subscriptions"
+ print("Requesting list of subscriptions")
try:
yield iq.send(to=self.service)
except Exception, e:
- print "Subscription list failure: %s" % (e,)
+ print("Subscription list failure: %s" % (e,))
def rawDataIn(self, buf):
- print "RECV: %s" % unicode(buf, 'utf-8').encode('ascii', 'replace')
+ print("RECV: %s" % unicode(buf, 'utf-8').encode('ascii', 'replace'))
def rawDataOut(self, buf):
- print "SEND: %s" % unicode(buf, 'utf-8').encode('ascii', 'replace')
+ print("SEND: %s" % unicode(buf, 'utf-8').encode('ascii', 'replace'))
class PropfindRequestor(AuthorizedHTTPGetter):
@@ -345,14 +346,14 @@
principal = "/principals/users/%s/" % (self.username,)
name, homes = (yield self.getPrincipalDetails(principal))
if self.verbose:
- print name, homes
+ print(name, homes)
for home in homes:
paths.add(home)
for principal in (yield self.getProxyFor()):
name, homes = (yield self.getPrincipalDetails(principal,
includeCardDAV=False))
if self.verbose:
- print name, homes
+ print(name, homes)
for home in homes:
if home.startswith("/"):
# Only support homes on the same server for now.
@@ -371,11 +372,11 @@
if subscribeNodes:
self.startMonitoring(host, port, subscribeNodes)
else:
- print "No nodes to monitor"
+ print("No nodes to monitor")
reactor.stop()
except Exception, e:
- print "Error:", e
+ print("Error:", e)
reactor.stop()
@inlineCallbacks
@@ -434,12 +435,12 @@
name = displayName
except Exception, e:
- print "Unable to parse principal details", e
- print responseBody
+ print("Unable to parse principal details", e)
+ print(responseBody)
raise
except Exception, e:
- print "Unable to look up principal details", e
+ print("Unable to look up principal details", e)
raise
returnValue( (name, homes) )
@@ -489,12 +490,12 @@
proxies.add(href)
except Exception, e:
- print "Unable to parse proxy information", e
- print responseBody
+ print("Unable to parse proxy information", e)
+ print(responseBody)
raise
except Exception, e:
- print "Unable to look up who %s is a proxy for" % (self.username,)
+ print("Unable to look up who %s is a proxy for" % (self.username,))
raise
returnValue(proxies)
@@ -561,7 +562,7 @@
pushTransports = prop.find("{http://calendarserver.org/ns/}push-transports")
if pushTransports is not None:
if self.verbose:
- print "push-transports:\n\n", ElementTree.tostring(pushTransports)
+ print("push-transports:\n\n", ElementTree.tostring(pushTransports))
for transport in pushTransports.findall("{http://calendarserver.org/ns/}transport"):
if transport.attrib["type"] == "XMPP":
xmppServer = transport.find("{http://calendarserver.org/ns/}xmpp-server")
@@ -579,12 +580,12 @@
nodes[key] = (href.text, name, kind)
except Exception, e:
- print "Unable to parse push information", e
- print responseBody
+ print("Unable to parse push information", e)
+ print(responseBody)
raise
except Exception, e:
- print "Unable to look up push information for %s" % (self.username,)
+ print("Unable to look up push information for %s" % (self.username,))
raise
if host is None:
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/obliterate.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/obliterate.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/obliterate.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,6 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
"""
This tool scans wipes out user data without using slow store object apis
@@ -43,8 +44,8 @@
def usage(e=None):
if e:
- print e
- print ""
+ print(e)
+ print("")
try:
ObliterateOptions().opt_help()
except SystemExit:
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/principals.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/principals.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/principals.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,6 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import sys
import os
@@ -49,49 +50,49 @@
def usage(e=None):
if e:
if isinstance(e, UnknownRecordTypeError):
- print "Valid record types:"
+ print("Valid record types:")
for recordType in config.directory.recordTypes():
- print " %s" % (recordType,)
+ print(" %s" % (recordType,))
- print e
- print ""
+ print(e)
+ print("")
name = os.path.basename(sys.argv[0])
- print "usage: %s [options] action_flags principal [principal ...]" % (name,)
- print " %s [options] --list-principal-types" % (name,)
- print " %s [options] --list-principals type" % (name,)
- print ""
- print " Performs the given actions against the giving principals."
- print ""
- print " Principals are identified by one of the following:"
- print " Type and shortname (eg.: users:wsanchez)"
- #print " A principal path (eg.: /principals/users/wsanchez/)"
- print " A GUID (eg.: E415DBA7-40B5-49F5-A7CC-ACC81E4DEC79)"
- print ""
- print "options:"
- print " -h --help: print this help and exit"
- print " -f --config <path>: Specify caldavd.plist configuration path"
- print " -v --verbose: print debugging information"
- print ""
- print "actions:"
- print " --search <search-string>: search for matching principals"
- print " --list-principal-types: list all of the known principal types"
- print " --list-principals type: list all principals of the given type"
- print " --read-property=property: read DAV property (eg.: {DAV:}group-member-set)"
- print " --list-read-proxies: list proxies with read-only access"
- print " --list-write-proxies: list proxies with read-write access"
- print " --list-proxies: list all proxies"
- print " --add-read-proxy=principal: add a read-only proxy"
- print " --add-write-proxy=principal: add a read-write proxy"
- print " --remove-proxy=principal: remove a proxy"
- print " --set-auto-schedule={true|false}: set auto-accept state"
- print " --get-auto-schedule: read auto-schedule state"
- print " --set-auto-schedule-mode={default|none|accept-always|decline-always|accept-if-free|decline-if-busy|automatic}: set auto-schedule mode"
- print " --get-auto-schedule-mode: read auto-schedule mode"
- print " --set-auto-accept-group=principal: set auto-accept-group"
- print " --get-auto-accept-group: read auto-accept-group"
- print " --add {locations|resources} 'full name' [record name] [GUID]: add a principal"
- print " --remove: remove a principal"
+ print("usage: %s [options] action_flags principal [principal ...]" % (name,))
+ print(" %s [options] --list-principal-types" % (name,))
+ print(" %s [options] --list-principals type" % (name,))
+ print("")
+ print(" Performs the given actions against the giving principals.")
+ print("")
+ print(" Principals are identified by one of the following:")
+ print(" Type and shortname (eg.: users:wsanchez)")
+ #print(" A principal path (eg.: /principals/users/wsanchez/)")
+ print(" A GUID (eg.: E415DBA7-40B5-49F5-A7CC-ACC81E4DEC79)")
+ print("")
+ print("options:")
+ print(" -h --help: print this help and exit")
+ print(" -f --config <path>: Specify caldavd.plist configuration path")
+ print(" -v --verbose: print debugging information")
+ print("")
+ print("actions:")
+ print(" --search <search-string>: search for matching principals")
+ print(" --list-principal-types: list all of the known principal types")
+ print(" --list-principals type: list all principals of the given type")
+ print(" --read-property=property: read DAV property (eg.: {DAV:}group-member-set)")
+ print(" --list-read-proxies: list proxies with read-only access")
+ print(" --list-write-proxies: list proxies with read-write access")
+ print(" --list-proxies: list all proxies")
+ print(" --add-read-proxy=principal: add a read-only proxy")
+ print(" --add-write-proxy=principal: add a read-write proxy")
+ print(" --remove-proxy=principal: remove a proxy")
+ print(" --set-auto-schedule={true|false}: set auto-accept state")
+ print(" --get-auto-schedule: read auto-schedule state")
+ print(" --set-auto-schedule-mode={default|none|accept-always|decline-always|accept-if-free|decline-if-busy|automatic}: set auto-schedule mode")
+ print(" --get-auto-schedule-mode: read auto-schedule mode")
+ print(" --set-auto-accept-group=principal: set auto-accept-group")
+ print(" --get-auto-accept-group: read auto-accept-group")
+ print(" --add {locations|resources} 'full name' [record name] [GUID]: add a principal")
+ print(" --remove: remove a principal")
if e:
sys.exit(64)
@@ -298,7 +299,7 @@
usage("Too many arguments")
for recordType in config.directory.recordTypes():
- print recordType
+ print(recordType)
return
@@ -307,13 +308,13 @@
try:
addType = matchStrings(addType, ["locations", "resources"])
except ValueError, e:
- print e
+ print(e)
return
try:
fullName, shortName, guid = parseCreationArgs(args)
except ValueError, e:
- print e
+ print(e)
return
if shortName is not None:
@@ -329,7 +330,7 @@
listPrincipals = matchStrings(listPrincipals, ["users", "groups",
"locations", "resources"])
except ValueError, e:
- print e
+ print(e)
return
if args:
@@ -340,7 +341,7 @@
if records:
printRecordList(records)
else:
- print "No records of type %s" % (listPrincipals,)
+ print("No records of type %s" % (listPrincipals,))
except UnknownRecordTypeError, e:
usage(e)
@@ -390,7 +391,7 @@
# Performs requested actions
for action in actions:
(yield action[0](principal, *action[1:]))
- print ""
+ print("")
finally:
#
@@ -409,25 +410,25 @@
records = list((yield config.directory.recordsMatchingTokens(searchTerm.strip().split())))
if records:
records.sort(key=operator.attrgetter('fullName'))
- print "%d matches found:" % (len(records),)
+ print("%d matches found:" % (len(records),))
for record in records:
- print "\n%s (%s)" % (record.fullName,
+ print("\n%s (%s)" % (record.fullName,
{ "users" : "User",
"groups" : "Group",
"locations" : "Place",
"resources" : "Resource",
}.get(record.recordType),
- )
- print " GUID: %s" % (record.guid,)
- print " Record name(s): %s" % (", ".join(record.shortNames),)
+ ))
+ print(" GUID: %s" % (record.guid,))
+ print(" Record name(s): %s" % (", ".join(record.shortNames),))
if record.authIDs:
- print " Auth ID(s): %s" % (", ".join(record.authIDs),)
+ print(" Auth ID(s): %s" % (", ".join(record.authIDs),))
if record.emailAddresses:
- print " Email(s): %s" % (", ".join(record.emailAddresses),)
+ print(" Email(s): %s" % (", ".join(record.emailAddresses),))
else:
- print "No matches found"
+ print("No matches found")
- print ""
+ print("")
finally:
#
@@ -441,9 +442,9 @@
try:
yield updateRecord(True, config.directory, addType, guid=guid,
shortNames=shortNames, fullName=fullName)
- print "Added '%s'" % (fullName,)
+ print("Added '%s'" % (fullName,))
except DirectoryError, e:
- print e
+ print(e)
finally:
#
@@ -523,32 +524,32 @@
guid = record.guid
config.directory.destroyRecord(record.recordType, guid=guid)
- print "Removed '%s' %s %s" % (fullName, shortName, guid)
+ print("Removed '%s' %s %s" % (fullName, shortName, guid))
@inlineCallbacks
def action_readProperty(resource, qname):
property = (yield resource.readProperty(qname, None))
- print "%r on %s:" % (encodeXMLName(*qname), resource)
- print ""
- print property.toxml()
+ print("%r on %s:" % (encodeXMLName(*qname), resource))
+ print("")
+ print(property.toxml())
@inlineCallbacks
def action_listProxies(principal, *proxyTypes):
for proxyType in proxyTypes:
subPrincipal = proxySubprincipal(principal, proxyType)
if subPrincipal is None:
- print "No %s proxies for %s" % (proxyType,
- prettyPrincipal(principal))
+ print("No %s proxies for %s" % (proxyType,
+ prettyPrincipal(principal)))
continue
membersProperty = (yield subPrincipal.readProperty(davxml.GroupMemberSet, None))
if membersProperty.children:
- print "%s proxies for %s:" % (
+ print("%s proxies for %s:" % (
{"read": "Read-only", "write": "Read/write"}[proxyType],
prettyPrincipal(principal)
- )
+ ))
records = []
for member in membersProperty.children:
proxyPrincipal = principalForPrincipalID(str(member),
@@ -558,15 +559,15 @@
printRecordList(records)
print
else:
- print "No %s proxies for %s" % (proxyType,
- prettyPrincipal(principal))
+ print("No %s proxies for %s" % (proxyType,
+ prettyPrincipal(principal)))
@inlineCallbacks
def action_addProxy(principal, proxyType, *proxyIDs):
for proxyID in proxyIDs:
proxyPrincipal = principalForPrincipalID(proxyID)
if proxyPrincipal is None:
- print "Invalid principal ID: %s" % (proxyID,)
+ print("Invalid principal ID: %s" % (proxyID,))
else:
(yield action_addProxyPrincipal(principal, proxyType, proxyPrincipal))
@@ -574,13 +575,13 @@
def action_addProxyPrincipal(principal, proxyType, proxyPrincipal):
try:
(yield addProxy(principal, proxyType, proxyPrincipal))
- print "Added %s as a %s proxy for %s" % (
+ print("Added %s as a %s proxy for %s" % (
prettyPrincipal(proxyPrincipal), proxyType,
- prettyPrincipal(principal))
+ prettyPrincipal(principal)))
except ProxyError, e:
- print "Error:", e
+ print("Error:", e)
except ProxyWarning, e:
- print e
+ print(e)
@inlineCallbacks
def addProxy(principal, proxyType, proxyPrincipal):
@@ -671,7 +672,7 @@
for proxyID in proxyIDs:
proxyPrincipal = principalForPrincipalID(proxyID)
if proxyPrincipal is None:
- print "Invalid principal ID: %s" % (proxyID,)
+ print("Invalid principal ID: %s" % (proxyID,))
else:
(yield action_removeProxyPrincipal(principal, proxyPrincipal, **kwargs))
@@ -680,13 +681,13 @@
try:
removed = (yield removeProxy(principal, proxyPrincipal, **kwargs))
if removed:
- print "Removed %s as a proxy for %s" % (
+ print("Removed %s as a proxy for %s" % (
prettyPrincipal(proxyPrincipal),
- prettyPrincipal(principal))
+ prettyPrincipal(principal)))
except ProxyError, e:
- print "Error:", e
+ print("Error:", e)
except ProxyWarning, e:
- print e
+ print(e)
@inlineCallbacks
@@ -725,16 +726,16 @@
@inlineCallbacks
def action_setAutoSchedule(principal, autoSchedule):
if principal.record.recordType == "groups":
- print "Enabling auto-schedule for %s is not allowed." % (principal,)
+ print("Enabling auto-schedule for %s is not allowed." % (principal,))
elif principal.record.recordType == "users" and not config.Scheduling.Options.AutoSchedule.AllowUsers:
- print "Enabling auto-schedule for %s is not allowed." % (principal,)
+ print("Enabling auto-schedule for %s is not allowed." % (principal,))
else:
- print "Setting auto-schedule to %s for %s" % (
+ print("Setting auto-schedule to %s for %s" % (
{ True: "true", False: "false" }[autoSchedule],
prettyPrincipal(principal),
- )
+ ))
(yield updateRecord(False, config.directory,
principal.record.recordType,
@@ -747,24 +748,24 @@
def action_getAutoSchedule(principal):
autoSchedule = principal.getAutoSchedule()
- print "Auto-schedule for %s is %s" % (
+ print("Auto-schedule for %s is %s" % (
prettyPrincipal(principal),
{ True: "true", False: "false" }[autoSchedule],
- )
+ ))
@inlineCallbacks
def action_setAutoScheduleMode(principal, autoScheduleMode):
if principal.record.recordType == "groups":
- print "Setting auto-schedule mode for %s is not allowed." % (principal,)
+ print("Setting auto-schedule mode for %s is not allowed." % (principal,))
elif principal.record.recordType == "users" and not config.Scheduling.Options.AutoSchedule.AllowUsers:
- print "Setting auto-schedule mode for %s is not allowed." % (principal,)
+ print("Setting auto-schedule mode for %s is not allowed." % (principal,))
else:
- print "Setting auto-schedule mode to %s for %s" % (
+ print("Setting auto-schedule mode to %s for %s" % (
autoScheduleMode,
prettyPrincipal(principal),
- )
+ ))
(yield updateRecord(False, config.directory,
principal.record.recordType,
@@ -779,28 +780,28 @@
autoScheduleMode = principal.getAutoScheduleMode()
if not autoScheduleMode:
autoScheduleMode = "automatic"
- print "Auto-schedule mode for %s is %s" % (
+ print("Auto-schedule mode for %s is %s" % (
prettyPrincipal(principal),
autoScheduleMode,
- )
+ ))
@inlineCallbacks
def action_setAutoAcceptGroup(principal, autoAcceptGroup):
if principal.record.recordType == "groups":
- print "Setting auto-accept-group for %s is not allowed." % (principal,)
+ print("Setting auto-accept-group for %s is not allowed." % (principal,))
elif principal.record.recordType == "users" and not config.Scheduling.Options.AutoSchedule.AllowUsers:
- print "Setting auto-accept-group for %s is not allowed." % (principal,)
+ print("Setting auto-accept-group for %s is not allowed." % (principal,))
else:
groupPrincipal = principalForPrincipalID(autoAcceptGroup)
if groupPrincipal is None or groupPrincipal.record.recordType != "groups":
- print "Invalid principal ID: %s" % (autoAcceptGroup,)
+ print("Invalid principal ID: %s" % (autoAcceptGroup,))
else:
- print "Setting auto-accept-group to %s for %s" % (
+ print("Setting auto-accept-group to %s for %s" % (
prettyPrincipal(groupPrincipal),
prettyPrincipal(principal),
- )
+ ))
(yield updateRecord(False, config.directory,
principal.record.recordType,
@@ -818,14 +819,14 @@
if record is not None:
groupPrincipal = config.directory.principalCollection.principalForUID(record.uid)
if groupPrincipal is not None:
- print "Auto-accept-group for %s is %s" % (
+ print("Auto-accept-group for %s is %s" % (
prettyPrincipal(principal),
prettyPrincipal(groupPrincipal),
- )
+ ))
return
- print "Invalid auto-accept-group assigned: %s" % (autoAcceptGroup,)
+ print("Invalid auto-accept-group assigned: %s" % (autoAcceptGroup,))
else:
- print "No auto-accept-group assigned to %s" % (prettyPrincipal(principal),)
+ print("No auto-accept-group assigned to %s" % (prettyPrincipal(principal),))
def abort(msg, status=1):
@@ -894,10 +895,10 @@
for record in records]
results.sort()
format = "%-22s %-17s %s"
- print format % ("Full name", "Record name", "UUID")
- print format % ("---------", "-----------", "----")
+ print(format % ("Full name", "Record name", "UUID"))
+ print(format % ("---------", "-----------", "----"))
for fullName, shortName, guid in results:
- print format % (fullName, shortName, guid)
+ print(format % (fullName, shortName, guid))
def prettyPrincipal(principal):
record = principal.record
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/purge.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/purge.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/purge.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,6 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
from calendarserver.tap.util import FakeRequest
from calendarserver.tap.util import getRootResource
@@ -107,19 +108,19 @@
def usage(cls, e=None):
name = os.path.basename(sys.argv[0])
- print "usage: %s [options]" % (name,)
- print ""
- print " Remove old events from the calendar server"
- print ""
- print "options:"
- print " -h --help: print this help and exit"
- print " -f --config <path>: Specify caldavd.plist configuration path"
- print " -d --days <number>: specify how many days in the past to retain (default=%d)" % (DEFAULT_RETAIN_DAYS,)
- #print " -b --batch <number>: number of events to remove in each transaction (default=%d)" % (DEFAULT_BATCH_SIZE,)
- print " -n --dry-run: calculate how many events to purge, but do not purge data"
- print " -v --verbose: print progress information"
- print " -D --debug: debug logging"
- print ""
+ print("usage: %s [options]" % (name,))
+ print("")
+ print(" Remove old events from the calendar server")
+ print("")
+ print("options:")
+ print(" -h --help: print this help and exit")
+ print(" -f --config <path>: Specify caldavd.plist configuration path")
+ print(" -d --days <number>: specify how many days in the past to retain (default=%d)" % (DEFAULT_RETAIN_DAYS,))
+ #print(" -b --batch <number>: number of events to remove in each transaction (default=%d)" % (DEFAULT_BATCH_SIZE,))
+ print(" -n --dry-run: calculate how many events to purge, but do not purge data")
+ print(" -v --verbose: print progress information")
+ print(" -D --debug: debug logging")
+ print("")
if e:
sys.stderr.write("%s\n" % (e,))
@@ -164,14 +165,14 @@
try:
days = int(arg)
except ValueError, e:
- print "Invalid value for --days: %s" % (arg,)
+ print("Invalid value for --days: %s" % (arg,))
cls.usage(e)
elif opt in ("-b", "--batch"):
try:
batchSize = int(arg)
except ValueError, e:
- print "Invalid value for --batch: %s" % (arg,)
+ print("Invalid value for --batch: %s" % (arg,))
cls.usage(e)
elif opt in ("-v", "--verbose"):
@@ -228,21 +229,21 @@
if self.dryrun:
if self.verbose:
- print "(Dry run) Searching for old events..."
+ print("(Dry run) Searching for old events...")
txn = self._store.newTransaction(label="Find old events")
oldEvents = (yield txn.eventsOlderThan(self.cutoff))
eventCount = len(oldEvents)
if self.verbose:
if eventCount == 0:
- print "No events are older than %s" % (self.cutoff,)
+ print("No events are older than %s" % (self.cutoff,))
elif eventCount == 1:
- print "1 event is older than %s" % (self.cutoff,)
+ print("1 event is older than %s" % (self.cutoff,))
else:
- print "%d events are older than %s" % (eventCount, self.cutoff)
+ print("%d events are older than %s" % (eventCount, self.cutoff))
returnValue(eventCount)
if self.verbose:
- print "Removing events older than %s..." % (self.cutoff,)
+ print("Removing events older than %s..." % (self.cutoff,))
numEventsRemoved = -1
totalRemoved = 0
@@ -253,16 +254,16 @@
if numEventsRemoved:
totalRemoved += numEventsRemoved
if self.verbose:
- print "%d," % (totalRemoved,),
+ print("%d," % (totalRemoved,),)
if self.verbose:
- print
+ print("")
if totalRemoved == 0:
- print "No events were removed"
+ print("No events were removed")
elif totalRemoved == 1:
- print "1 event was removed in total"
+ print("1 event was removed in total")
else:
- print "%d events were removed in total" % (totalRemoved,)
+ print("%d events were removed in total" % (totalRemoved,))
returnValue(totalRemoved)
@@ -280,20 +281,20 @@
def usage(cls, e=None):
name = os.path.basename(sys.argv[0])
- print "usage: %s [options]" % (name,)
- print ""
- print " Remove old or orphaned attachments from the calendar server"
- print ""
- print "options:"
- print " -h --help: print this help and exit"
- print " -f --config <path>: Specify caldavd.plist configuration path"
- print " -u --uuid <owner uid>: target a specific user UID"
- #print " -b --batch <number>: number of attachments to remove in each transaction (default=%d)" % (DEFAULT_BATCH_SIZE,)
- print " -d --days <number>: specify how many days in the past to retain (default=%d) zero means no removal of old attachments" % (DEFAULT_RETAIN_DAYS,)
- print " -n --dry-run: calculate how many attachments to purge, but do not purge data"
- print " -v --verbose: print progress information"
- print " -D --debug: debug logging"
- print ""
+ print("usage: %s [options]" % (name,))
+ print("")
+ print(" Remove old or orphaned attachments from the calendar server")
+ print("")
+ print("options:")
+ print(" -h --help: print this help and exit")
+ print(" -f --config <path>: Specify caldavd.plist configuration path")
+ print(" -u --uuid <owner uid>: target a specific user UID")
+ #print(" -b --batch <number>: number of attachments to remove in each transaction (default=%d)" % (DEFAULT_BATCH_SIZE,))
+ print(" -d --days <number>: specify how many days in the past to retain (default=%d) zero means no removal of old attachments" % (DEFAULT_RETAIN_DAYS,))
+ print(" -n --dry-run: calculate how many attachments to purge, but do not purge data")
+ print(" -v --verbose: print progress information")
+ print(" -D --debug: debug logging")
+ print("")
if e:
sys.stderr.write("%s\n" % (e,))
@@ -343,14 +344,14 @@
try:
days = int(arg)
except ValueError, e:
- print "Invalid value for --days: %s" % (arg,)
+ print("Invalid value for --days: %s" % (arg,))
cls.usage(e)
elif opt in ("-b", "--batch"):
try:
batchSize = int(arg)
except ValueError, e:
- print "Invalid value for --batch: %s" % (arg,)
+ print("Invalid value for --batch: %s" % (arg,))
cls.usage(e)
elif opt in ("-v", "--verbose"):
@@ -438,7 +439,7 @@
def _orphansDryRun(self):
if self.verbose:
- print "(Dry run) Searching for orphaned attachments..."
+ print("(Dry run) Searching for orphaned attachments...")
txn = self._store.newTransaction(label="Find orphaned attachments")
orphans = (yield txn.orphanedAttachments(self.uuid))
returnValue(orphans)
@@ -448,7 +449,7 @@
def _dropboxDryRun(self):
if self.verbose:
- print "(Dry run) Searching for old dropbox attachments..."
+ print("(Dry run) Searching for old dropbox attachments...")
txn = self._store.newTransaction(label="Find old dropbox attachments")
cutoffs = (yield txn.oldDropboxAttachments(self.cutoff, self.uuid))
yield txn.commit()
@@ -460,7 +461,7 @@
def _managedDryRun(self):
if self.verbose:
- print "(Dry run) Searching for old managed attachments..."
+ print("(Dry run) Searching for old managed attachments...")
txn = self._store.newTransaction(label="Find old managed attachments")
cutoffs = (yield txn.oldManagedAttachments(self.cutoff, self.uuid))
yield txn.commit()
@@ -525,8 +526,8 @@
table.addFooter(("Total:", "",) + tuple(totals))
total = totals[7]
- print "\n"
- print "Orphaned/Old Attachments by User:\n"
+ print("\n")
+ print("Orphaned/Old Attachments by User:\n")
table.printTable()
else:
total = sum([x[3] for x in orphans]) + sum([x[3] for x in dropbox]) + sum([x[3] for x in managed])
@@ -538,7 +539,7 @@
def _orphansPurge(self):
if self.verbose:
- print "Removing orphaned attachments...",
+ print("Removing orphaned attachments...",)
numOrphansRemoved = -1
totalRemoved = 0
@@ -549,18 +550,18 @@
if numOrphansRemoved:
totalRemoved += numOrphansRemoved
if self.verbose:
- print " %d," % (totalRemoved,),
+ print(" %d," % (totalRemoved,),)
elif self.verbose:
- print
+ print("")
if self.verbose:
if totalRemoved == 0:
- print "No orphaned attachments were removed"
+ print("No orphaned attachments were removed")
elif totalRemoved == 1:
- print "1 orphaned attachment was removed in total"
+ print("1 orphaned attachment was removed in total")
else:
- print "%d orphaned attachments were removed in total" % (totalRemoved,)
- print
+ print("%d orphaned attachments were removed in total" % (totalRemoved,))
+ print("")
returnValue(totalRemoved)
@@ -569,7 +570,7 @@
def _dropboxPurge(self):
if self.verbose:
- print "Removing old dropbox attachments...",
+ print("Removing old dropbox attachments...",)
numOldRemoved = -1
totalRemoved = 0
@@ -580,18 +581,18 @@
if numOldRemoved:
totalRemoved += numOldRemoved
if self.verbose:
- print " %d," % (totalRemoved,),
+ print(" %d," % (totalRemoved,),)
elif self.verbose:
- print
+ print("")
if self.verbose:
if totalRemoved == 0:
- print "No old dropbox attachments were removed"
+ print("No old dropbox attachments were removed")
elif totalRemoved == 1:
- print "1 old dropbox attachment was removed in total"
+ print("1 old dropbox attachment was removed in total")
else:
- print "%d old dropbox attachments were removed in total" % (totalRemoved,)
- print
+ print("%d old dropbox attachments were removed in total" % (totalRemoved,))
+ print("")
returnValue(totalRemoved)
@@ -600,7 +601,7 @@
def _managedPurge(self):
if self.verbose:
- print "Removing old managed attachments...",
+ print("Removing old managed attachments...",)
numOldRemoved = -1
totalRemoved = 0
@@ -611,18 +612,18 @@
if numOldRemoved:
totalRemoved += numOldRemoved
if self.verbose:
- print " %d," % (totalRemoved,),
+ print(" %d," % (totalRemoved,),)
elif self.verbose:
- print
+ print("")
if self.verbose:
if totalRemoved == 0:
- print "No old managed attachments were removed"
+ print("No old managed attachments were removed")
elif totalRemoved == 1:
- print "1 old managed attachment was removed in total"
+ print("1 old managed attachment was removed in total")
else:
- print "%d old managed attachments were removed in total" % (totalRemoved,)
- print
+ print("%d old managed attachments were removed in total" % (totalRemoved,))
+ print("")
returnValue(totalRemoved)
@@ -644,18 +645,18 @@
def usage(cls, e=None):
name = os.path.basename(sys.argv[0])
- print "usage: %s [options]" % (name,)
- print ""
- print " Remove a principal's events and contacts from the calendar server"
- print ""
- print "options:"
- print " -c --completely: By default, only future events are canceled; this option cancels all events"
- print " -h --help: print this help and exit"
- print " -f --config <path>: Specify caldavd.plist configuration path"
- print " -n --dry-run: calculate how many events and contacts to purge, but do not purge data"
- print " -v --verbose: print progress information"
- print " -D --debug: debug logging"
- print ""
+ print("usage: %s [options]" % (name,))
+ print("")
+ print(" Remove a principal's events and contacts from the calendar server")
+ print("")
+ print("options:")
+ print(" -c --completely: By default, only future events are canceled; this option cancels all events")
+ print(" -h --help: print this help and exit")
+ print(" -f --config <path>: Specify caldavd.plist configuration path")
+ print(" -n --dry-run: calculate how many events and contacts to purge, but do not purge data")
+ print(" -v --verbose: print progress information")
+ print(" -D --debug: debug logging")
+ print("")
if e:
sys.stderr.write("%s\n" % (e,))
@@ -769,9 +770,9 @@
if self.verbose:
amount = "%d event%s" % (total, "s" if total > 1 else "")
if self.dryrun:
- print "Would have modified or deleted %s" % (amount,)
+ print("Would have modified or deleted %s" % (amount,))
else:
- print "Modified or deleted %s" % (amount,)
+ print("Modified or deleted %s" % (amount,))
returnValue((total, allAssignments,))
@@ -819,9 +820,9 @@
for child in children:
if self.verbose:
if self.dryrun:
- print "Would unshare: %s" % (child.name(),)
+ print("Would unshare: %s" % (child.name(),))
else:
- print "Unsharing: %s" % (child.name(),)
+ print("Unsharing: %s" % (child.name(),))
if not self.dryrun:
(yield child.unshare())
@@ -895,9 +896,9 @@
)
if self.verbose:
if self.dryrun:
- print "Would modify: %s" % (uri,)
+ print("Would modify: %s" % (uri,))
else:
- print "Modifying: %s" % (uri,)
+ print("Modifying: %s" % (uri,))
if not self.dryrun:
result = (yield storer.run())
@@ -906,37 +907,37 @@
request._rememberResource(childResource, uri)
if self.verbose:
if self.dryrun:
- print "Would delete: %s" % (uri,)
+ print("Would delete: %s" % (uri,))
else:
- print "Deleting: %s" % (uri,)
+ print("Deleting: %s" % (uri,))
if not self.dryrun:
retry = False
try:
result = (yield childResource.storeRemove(request, self.doimplicit, uri))
if result != NO_CONTENT:
- print "Error deleting %s/%s/%s: %s" % (uid,
- collName, childName, result)
+ print("Error deleting %s/%s/%s: %s" % (uid,
+ collName, childName, result))
retry = True
else:
incrementCount = True
except Exception, e:
- print "Exception deleting %s/%s/%s: %s" % (uid,
- collName, childName, str(e))
+ print("Exception deleting %s/%s/%s: %s" % (uid,
+ collName, childName, str(e)))
retry = True
if retry and self.doimplicit:
# Try again with implicit scheduling off
- print "Retrying deletion of %s/%s/%s with implicit scheduling turned off" % (uid, collName, childName)
+ print("Retrying deletion of %s/%s/%s with implicit scheduling turned off" % (uid, collName, childName))
try:
result = (yield childResource.storeRemove(request, False, uri))
if result != NO_CONTENT:
- print "Error deleting %s/%s/%s: %s" % (uid,
- collName, childName, result)
+ print("Error deleting %s/%s/%s: %s" % (uid,
+ collName, childName, result))
else:
incrementCount = True
except Exception, e:
- print "Still couldn't delete %s/%s/%s even with implicit scheduling turned off: %s" % (uid, collName, childName, str(e))
+ print("Still couldn't delete %s/%s/%s even with implicit scheduling turned off: %s" % (uid, collName, childName, str(e)))
if incrementCount:
count += 1
@@ -968,18 +969,18 @@
calendarName = calColl.name()
if self.verbose:
if self.dryrun:
- print "Would delete calendar: %s" % (calendarName,)
+ print("Would delete calendar: %s" % (calendarName,))
else:
- print "Deleting calendar: %s" % (calendarName,)
+ print("Deleting calendar: %s" % (calendarName,))
if not self.dryrun:
(yield storeCalHome.removeChildWithName(calendarName))
if not remainingCalendars:
if self.verbose:
if self.dryrun:
- print "Would delete calendar home"
+ print("Would delete calendar home")
else:
- print "Deleting calendar home"
+ print("Deleting calendar home")
if not self.dryrun:
(yield storeCalHome.remove())
@@ -992,27 +993,27 @@
if self.verbose:
uri = "/addressbooks/__uids__/%s/%s/%s" % (uid, abColl.name(), cardName)
if self.dryrun:
- print "Would delete: %s" % (uri,)
+ print("Would delete: %s" % (uri,))
else:
- print "Deleting: %s" % (uri,)
+ print("Deleting: %s" % (uri,))
if not self.dryrun:
(yield abColl.removeObjectResourceWithName(cardName))
count += 1
if self.verbose:
abName = abColl.name()
if self.dryrun:
- print "Would delete addressbook: %s" % (abName,)
+ print("Would delete addressbook: %s" % (abName,))
else:
- print "Deleting addressbook: %s" % (abName,)
+ print("Deleting addressbook: %s" % (abName,))
if not self.dryrun:
# Also remove the addressbook collection itself
(yield storeAbHome.removeChildWithName(abColl.name()))
if self.verbose:
if self.dryrun:
- print "Would delete addressbook home"
+ print("Would delete addressbook home")
else:
- print "Deleting addressbook home"
+ print("Deleting addressbook home")
if not self.dryrun:
(yield storeAbHome.remove())
@@ -1026,7 +1027,7 @@
if self.proxies and not self.dryrun:
if self.verbose:
- print "Deleting any proxy assignments"
+ print("Deleting any proxy assignments")
assignments = (yield self._purgeProxyAssignments(principal))
returnValue((count, assignments))
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/push.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/push.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/push.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
from calendarserver.tap.util import getRootResource
from calendarserver.tools.cmdline import utilityMain
@@ -33,15 +34,15 @@
def usage(e=None):
name = os.path.basename(sys.argv[0])
- print "usage: %s [options] [user ...]" % (name,)
- print ""
- print " Display Apple Push Notification subscriptions"
- print ""
- print "options:"
- print " -h --help: print this help and exit"
- print " -f --config <path>: Specify caldavd.plist configuration path"
- print " -D --debug: debug logging"
- print ""
+ print("usage: %s [options] [user ...]" % (name,))
+ print("")
+ print(" Display Apple Push Notification subscriptions")
+ print("")
+ print("options:")
+ print(" -h --help: print this help and exit")
+ print(" -f --config <path>: Specify caldavd.plist configuration path")
+ print(" -D --debug: debug logging")
+ print("")
if e:
sys.stderr.write("%s\n" % (e,))
@@ -157,7 +158,7 @@
print
record = directory.recordWithShortName("users", user)
if record is not None:
- print "User %s (%s)..." % (user, record.uid)
+ print("User %s (%s)..." % (user, record.uid))
txn = store.newTransaction(label="Display APN Subscriptions")
subscriptions = (yield txn.apnSubscriptionsBySubscriber(record.uid))
(yield txn.commit())
@@ -180,15 +181,20 @@
record = directory.recordWithUID(uid)
user = record.shortNames[0]
if collection:
- print "...is subscribed to a share from %s's %s home" % (user, resource),
+ print("...is subscribed to a share from %s's %s home" % (user, resource),)
else:
- print "...is subscribed to %s's %s home" % (user, resource),
- # print " (key: %s)\n" % (key,)
- print "with %d device(s):" % (len(tokens),)
+ print("...is subscribed to %s's %s home" % (user, resource),)
+ # print(" (key: %s)\n" % (key,))
+ print("with %d device(s):" % (len(tokens),))
for token, timestamp, userAgent, ipAddr in tokens:
- print " %s\n '%s' from %s\n %s" % (token, userAgent, ipAddr,
- time.strftime("on %a, %d %b %Y at %H:%M:%S %z(%Z)", time.localtime(timestamp)))
+ print(" %s\n '%s' from %s\n %s" % (
+ token, userAgent, ipAddr,
+ time.strftime(
+ "on %a, %d %b %Y at %H:%M:%S %z(%Z)",
+ time.localtime(timestamp)
+ )
+ ))
else:
- print " ...is not subscribed to anything."
+ print(" ...is not subscribed to anything.")
else:
- print "User %s not found" % (user,)
+ print("User %s not found" % (user,))
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/resources.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/resources.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/resources.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,6 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
from calendarserver.tools.util import loadConfig, getDirectory, setupMemcached, checkDirectory
from getopt import getopt, GetoptError
@@ -39,15 +40,15 @@
def usage():
name = os.path.basename(sys.argv[0])
- print "usage: %s [options] " % (name,)
- print ""
- print " Migrates resources and locations from OD to Calendar Server"
- print ""
- print "options:"
- print " -h --help: print this help and exit"
- print " -f --config <path>: Specify caldavd.plist configuration path"
- print " -v --verbose: print debugging information"
- print ""
+ print("usage: %s [options] " % (name,))
+ print("")
+ print(" Migrates resources and locations from OD to Calendar Server")
+ print("")
+ print("options:")
+ print(" -h --help: print this help and exit")
+ print(" -f --config <path>: Specify caldavd.plist configuration path")
+ print(" -v --verbose: print debugging information")
+ print("")
sys.exit(0)
@@ -175,7 +176,7 @@
]
if verbose:
- print "Querying for all %s records" % (recordType,)
+ print("Querying for all %s records" % (recordType,))
results = list(sourceService.odModule.listAllRecordsWithAttributes_list(
sourceService.directory,
@@ -184,7 +185,7 @@
))
if verbose:
- print "Found %d records" % (len(results),)
+ print("Found %d records" % (len(results),))
return results
@@ -210,7 +211,7 @@
record = destService.recordWithGUID(guid)
if record is None:
if verbose:
- print "Migrating %s (%s)" % (fullName, recordType)
+ print("Migrating %s (%s)" % (fullName, recordType))
if autoSchedules is not None:
autoSchedule = autoSchedules.get(guid, 1)
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/shell/terminal.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/shell/terminal.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/shell/terminal.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
"""
Interactive shell for terminals.
@@ -56,8 +57,8 @@
def usage(e=None):
if e:
- print e
- print ""
+ print(e)
+ print("")
try:
ShellOptions().opt_help()
except SystemExit:
@@ -340,7 +341,7 @@
if tokens:
cmd = tokens.pop(0)
- #print "Arguments: %r" % (tokens,)
+ #print("Arguments: %r" % (tokens,))
m = getattr(self.commands, "cmd_%s" % (cmd,), None)
if m:
@@ -410,6 +411,6 @@
directory = getDirectory()
return ShellService(store, directory, options, reactor, config)
- print "Initializing shell..."
+ print("Initializing shell...")
utilityMain(options["config"], makeService, reactor)
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/test/test_calverify.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/test/test_calverify.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/test/test_calverify.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
"""
Tests for calendarserver.tools.calverify
@@ -20,7 +21,8 @@
from StringIO import StringIO
from calendarserver.tap.util import getRootResource
-from calendarserver.tools.calverify import CalVerifyService
+from calendarserver.tools.calverify import BadDataService, \
+ SchedulingMismatchService, DoubleBookingService
from pycalendar.datetime import PyCalendarDateTime
from twisted.internet import reactor
from twisted.internet.defer import inlineCallbacks, returnValue
@@ -530,6 +532,7 @@
options = {
"ical": True,
+ "fix": False,
"nobase64": False,
"verbose": False,
"uid": "",
@@ -537,9 +540,9 @@
"tzid": "",
}
output = StringIO()
- calverify = CalVerifyService(self._sqlCalendarStore, options, output, reactor, config)
+ calverify = BadDataService(self._sqlCalendarStore, options, output, reactor, config)
calverify.emailDomain = "example.com"
- yield calverify.doScan(True, False, False)
+ yield calverify.doAction()
self.assertEqual(calverify.results["Number of events to process"], 13)
self.verifyResultsByUID(calverify.results["Bad iCalendar data"], set((
@@ -572,6 +575,7 @@
options = {
"ical": True,
+ "fix": True,
"nobase64": False,
"verbose": False,
"uid": "",
@@ -583,9 +587,9 @@
# Do fix
self.patch(config.Scheduling.Options, "PrincipalHostAliases", "demo.com")
self.patch(config, "HTTPPort", 8008)
- calverify = CalVerifyService(self._sqlCalendarStore, options, output, reactor, config)
+ calverify = BadDataService(self._sqlCalendarStore, options, output, reactor, config)
calverify.emailDomain = "example.com"
- yield calverify.doScan(True, False, True)
+ yield calverify.doAction()
self.assertEqual(calverify.results["Number of events to process"], 13)
self.verifyResultsByUID(calverify.results["Bad iCalendar data"], set((
@@ -603,9 +607,10 @@
)))
# Do scan
- calverify = CalVerifyService(self._sqlCalendarStore, options, output, reactor, config)
+ options["fix"] = False
+ calverify = BadDataService(self._sqlCalendarStore, options, output, reactor, config)
calverify.emailDomain = "example.com"
- yield calverify.doScan(True, False, False)
+ yield calverify.doAction()
self.assertEqual(calverify.results["Number of events to process"], 13)
self.verifyResultsByUID(calverify.results["Bad iCalendar data"], set((
@@ -640,6 +645,7 @@
options = {
"ical": False,
+ "fix": False,
"badcua": True,
"nobase64": False,
"verbose": False,
@@ -648,9 +654,9 @@
"tzid": "",
}
output = StringIO()
- calverify = CalVerifyService(self._sqlCalendarStore, options, output, reactor, config)
+ calverify = BadDataService(self._sqlCalendarStore, options, output, reactor, config)
calverify.emailDomain = "example.com"
- yield calverify.doScan(True, False, False)
+ yield calverify.doAction()
self.assertEqual(calverify.results["Number of events to process"], 13)
self.verifyResultsByUID(calverify.results["Bad iCalendar data"], set((
@@ -679,6 +685,7 @@
options = {
"ical": False,
+ "fix": True,
"badcua": True,
"nobase64": False,
"verbose": False,
@@ -691,9 +698,9 @@
# Do fix
self.patch(config.Scheduling.Options, "PrincipalHostAliases", "demo.com")
self.patch(config, "HTTPPort", 8008)
- calverify = CalVerifyService(self._sqlCalendarStore, options, output, reactor, config)
+ calverify = BadDataService(self._sqlCalendarStore, options, output, reactor, config)
calverify.emailDomain = "example.com"
- yield calverify.doScan(True, False, True)
+ yield calverify.doAction()
self.assertEqual(calverify.results["Number of events to process"], 13)
self.verifyResultsByUID(calverify.results["Bad iCalendar data"], set((
@@ -707,9 +714,10 @@
)))
# Do scan
- calverify = CalVerifyService(self._sqlCalendarStore, options, output, reactor, config)
+ options["fix"] = False
+ calverify = BadDataService(self._sqlCalendarStore, options, output, reactor, config)
calverify.emailDomain = "example.com"
- yield calverify.doScan(True, False, False)
+ yield calverify.doAction()
self.assertEqual(calverify.results["Number of events to process"], 13)
self.verifyResultsByUID(calverify.results["Bad iCalendar data"], set((
@@ -907,7 +915,7 @@
"uuid": "",
"tzid": "",
}
- calverifyNo64 = CalVerifyService(self._sqlCalendarStore, optionsNo64, StringIO(), reactor, config)
+ calverifyNo64 = BadDataService(self._sqlCalendarStore, optionsNo64, StringIO(), reactor, config)
calverifyNo64.emailDomain = "example.com"
options64 = {
@@ -918,7 +926,7 @@
"uuid": "",
"tzid": "",
}
- calverify64 = CalVerifyService(self._sqlCalendarStore, options64, StringIO(), reactor, config)
+ calverify64 = BadDataService(self._sqlCalendarStore, options64, StringIO(), reactor, config)
calverify64.emailDomain = "example.com"
for bad, oknobase64, okbase64 in data:
@@ -1467,15 +1475,17 @@
"badcua": False,
"mismatch": True,
"nobase64": False,
+ "fix": False,
"verbose": False,
"details": False,
"uid": "",
"uuid": "",
"tzid": "",
+ "start": PyCalendarDateTime(now, 1, 1, 0, 0, 0),
}
output = StringIO()
- calverify = CalVerifyService(self._sqlCalendarStore, options, output, reactor, config)
- yield calverify.doScan(False, True, False, start=PyCalendarDateTime(now, 1, 1, 0, 0, 0))
+ calverify = SchedulingMismatchService(self._sqlCalendarStore, options, output, reactor, config)
+ yield calverify.doAction()
self.assertEqual(calverify.results["Number of events to process"], 17)
self.assertEqual(calverify.results["Missing Attendee"], set((
@@ -1505,7 +1515,7 @@
self.assertTrue("Fix remove" not in calverify.results)
self.assertTrue("Fix remove" not in calverify.results)
self.assertTrue("Fix failures" not in calverify.results)
- self.assertTrue("Fixed Auto-Accepts" not in calverify.results)
+ self.assertTrue("Auto-Accepts" not in calverify.results)
sync_token_new1 = (yield (yield self.calendarUnderTest(self.uuid1)).syncToken())
sync_token_new2 = (yield (yield self.calendarUnderTest(self.uuid2)).syncToken())
@@ -1532,15 +1542,17 @@
"badcua": False,
"mismatch": True,
"nobase64": False,
+ "fix": True,
"verbose": False,
"details": False,
"uid": "",
"uuid": "",
"tzid": "",
+ "start": PyCalendarDateTime(now, 1, 1, 0, 0, 0),
}
output = StringIO()
- calverify = CalVerifyService(self._sqlCalendarStore, options, output, reactor, config)
- yield calverify.doScan(False, True, True, start=PyCalendarDateTime(now, 1, 1, 0, 0, 0))
+ calverify = SchedulingMismatchService(self._sqlCalendarStore, options, output, reactor, config)
+ yield calverify.doAction()
self.assertEqual(calverify.results["Number of events to process"], 17)
self.assertEqual(calverify.results["Missing Attendee"], set((
@@ -1604,7 +1616,7 @@
self.assertEqual(obj, None)
self.assertEqual(calverify.results["Fix failures"], 0)
- self.assertEqual(calverify.results["Fixed Auto-Accepts"], [])
+ self.assertEqual(calverify.results["Auto-Accepts"], [])
sync_token_new1 = (yield (yield self.calendarUnderTest(self.uuid1)).syncToken())
sync_token_new2 = (yield (yield self.calendarUnderTest(self.uuid2)).syncToken())
@@ -1615,8 +1627,9 @@
# Re-scan after changes to make sure there are no errors
self.commit()
- calverify = CalVerifyService(self._sqlCalendarStore, options, output, reactor, config)
- yield calverify.doScan(False, True, False, start=PyCalendarDateTime(now, 1, 1, 0, 0, 0))
+ options["fix"] = False
+ calverify = SchedulingMismatchService(self._sqlCalendarStore, options, output, reactor, config)
+ yield calverify.doAction()
self.assertEqual(calverify.results["Number of events to process"], 14)
self.assertTrue("Missing Attendee" not in calverify.results)
@@ -1627,7 +1640,7 @@
self.assertTrue("Fix add inbox" not in calverify.results)
self.assertTrue("Fix remove" not in calverify.results)
self.assertTrue("Fix failures" not in calverify.results)
- self.assertTrue("Fixed Auto-Accepts" not in calverify.results)
+ self.assertTrue("Auto-Accepts" not in calverify.results)
@@ -1738,15 +1751,17 @@
"badcua": False,
"mismatch": True,
"nobase64": False,
+ "fix": False,
"verbose": False,
"details": False,
"uid": "",
"uuid": "",
"tzid": "",
+ "start": PyCalendarDateTime(now, 1, 1, 0, 0, 0),
}
output = StringIO()
- calverify = CalVerifyService(self._sqlCalendarStore, options, output, reactor, config)
- yield calverify.doScan(False, True, False, start=PyCalendarDateTime(now, 1, 1, 0, 0, 0))
+ calverify = SchedulingMismatchService(self._sqlCalendarStore, options, output, reactor, config)
+ yield calverify.doAction()
self.assertEqual(calverify.results["Number of events to process"], 3)
self.assertEqual(calverify.results["Missing Attendee"], set((
@@ -1763,7 +1778,7 @@
self.assertTrue("Fix add inbox" not in calverify.results)
self.assertTrue("Fix remove" not in calverify.results)
self.assertTrue("Fix failures" not in calverify.results)
- self.assertTrue("Fixed Auto-Accepts" not in calverify.results)
+ self.assertTrue("Auto-Accepts" not in calverify.results)
sync_token_new1 = (yield (yield self.calendarUnderTest(self.uuid1)).syncToken())
sync_token_newl1 = (yield (yield self.calendarUnderTest(self.uuidl1)).syncToken())
@@ -1787,15 +1802,17 @@
"badcua": False,
"mismatch": True,
"nobase64": False,
+ "fix": True,
"verbose": False,
"details": False,
"uid": "",
"uuid": "",
"tzid": "",
+ "start": PyCalendarDateTime(now, 1, 1, 0, 0, 0),
}
output = StringIO()
- calverify = CalVerifyService(self._sqlCalendarStore, options, output, reactor, config)
- yield calverify.doScan(False, True, True, start=PyCalendarDateTime(now, 1, 1, 0, 0, 0))
+ calverify = SchedulingMismatchService(self._sqlCalendarStore, options, output, reactor, config)
+ yield calverify.doAction()
self.assertEqual(calverify.results["Number of events to process"], 3)
self.assertEqual(calverify.results["Missing Attendee"], set((
@@ -1823,7 +1840,7 @@
self.assertTrue("Fix remove" not in calverify.results)
self.assertEqual(calverify.results["Fix failures"], 0)
- testResults = sorted(calverify.results["Fixed Auto-Accepts"], key=lambda x: x["uid"])
+ testResults = sorted(calverify.results["Auto-Accepts"], key=lambda x: x["uid"])
self.assertEqual(testResults[0]["path"], "/calendars/__uids__/%s/calendar/mismatched_attendee.ics" % self.uuidl1)
self.assertEqual(testResults[0]["uid"], "MISMATCH_ATTENDEE_ICS")
self.assertEqual(testResults[0]["start"].getText(), "%s0307T031500" % (now,))
@@ -1837,8 +1854,9 @@
# Re-scan after changes to make sure there are no errors
self.commit()
- calverify = CalVerifyService(self._sqlCalendarStore, options, output, reactor, config)
- yield calverify.doScan(False, True, False, start=PyCalendarDateTime(now, 1, 1, 0, 0, 0))
+ options["fix"] = False
+ calverify = SchedulingMismatchService(self._sqlCalendarStore, options, output, reactor, config)
+ yield calverify.doAction()
self.assertEqual(calverify.results["Number of events to process"], 4)
self.assertTrue("Missing Attendee" not in calverify.results)
@@ -1849,4 +1867,721 @@
self.assertTrue("Fix add inbox" not in calverify.results)
self.assertTrue("Fix remove" not in calverify.results)
self.assertTrue("Fix failures" not in calverify.results)
- self.assertTrue("Fixed Auto-Accepts" not in calverify.results)
+ self.assertTrue("Auto-Accepts" not in calverify.results)
+
+
+
+class CalVerifyMismatchTestsUUID(CalVerifyMismatchTestsBase):
+ """
+ Tests calverify for iCalendar mismatch problems for auto-accept attendees.
+ """
+
+ # Organizer has event, attendee do not
+ MISSING_ATTENDEE_1_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100303T181216Z
+UID:MISSING_ATTENDEE_ICS
+DTEND:%(year)s0307T151500Z
+TRANSP:OPAQUE
+SUMMARY:Ancient event
+DTSTART:%(year)s0307T111500Z
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
+ORGANIZER:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n") % {"year": now}
+
+ # Attendee partstat mismatch
+ MISMATCH_ATTENDEE_1_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100303T181216Z
+UID:MISMATCH_ATTENDEE_ICS
+DTEND:%(year)s0307T151500Z
+TRANSP:OPAQUE
+SUMMARY:Ancient event
+DTSTART:%(year)s0307T111500Z
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
+ORGANIZER:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE;PARTSTAT=ACCEPTED:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE;PARTSTAT=NEEDS-ACTION:urn:uuid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n") % {"year": now}
+
+ MISMATCH_ATTENDEE_L1_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100303T181216Z
+UID:MISMATCH_ATTENDEE_ICS
+DTEND:%(year)s0307T151500Z
+TRANSP:OPAQUE
+SUMMARY:Ancient event
+DTSTART:%(year)s0307T111500Z
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
+ORGANIZER:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE;PARTSTAT=ACCEPTED:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE;PARTSTAT=ACCEPTED:urn:uuid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n") % {"year": now}
+
+ requirements = {
+ CalVerifyMismatchTestsBase.uuid1 : {
+ "calendar" : {
+ "missing_attendee.ics" : (MISSING_ATTENDEE_1_ICS, CalVerifyMismatchTestsBase.metadata,),
+ "mismatched_attendee.ics" : (MISMATCH_ATTENDEE_1_ICS, CalVerifyMismatchTestsBase.metadata,),
+ },
+ "inbox" : {},
+ },
+ CalVerifyMismatchTestsBase.uuid2 : {
+ "calendar" : {},
+ "inbox" : {},
+ },
+ CalVerifyMismatchTestsBase.uuid3 : {
+ "calendar" : {},
+ "inbox" : {},
+ },
+ CalVerifyMismatchTestsBase.uuidl1 : {
+ "calendar" : {
+ "mismatched_attendee.ics" : (MISMATCH_ATTENDEE_L1_ICS, CalVerifyMismatchTestsBase.metadata,),
+ },
+ "inbox" : {},
+ },
+ }
+
+ @inlineCallbacks
+ def test_scanMismatchOnly(self):
+ """
+ CalVerifyService.doScan without fix for mismatches. Make sure it detects
+ as much as it can. Make sure sync-token is not changed.
+ """
+
+ sync_token_old1 = (yield (yield self.calendarUnderTest(self.uuid1)).syncToken())
+ sync_token_oldl1 = (yield (yield self.calendarUnderTest(self.uuidl1)).syncToken())
+ self.commit()
+
+ options = {
+ "ical": False,
+ "badcua": False,
+ "mismatch": True,
+ "nobase64": False,
+ "fix": False,
+ "verbose": False,
+ "details": False,
+ "uid": "",
+ "uuid": CalVerifyMismatchTestsBase.uuidl1,
+ "tzid": "",
+ "start": PyCalendarDateTime(now, 1, 1, 0, 0, 0),
+ }
+ output = StringIO()
+ calverify = SchedulingMismatchService(self._sqlCalendarStore, options, output, reactor, config)
+ yield calverify.doAction()
+
+ self.assertEqual(calverify.results["Number of events to process"], 2)
+ self.assertTrue("Missing Attendee" not in calverify.results)
+ self.assertEqual(calverify.results["Mismatch Attendee"], set((
+ ("MISMATCH_ATTENDEE_ICS", self.uuid1, self.uuidl1,),
+ )))
+ self.assertTrue("Missing Organizer" not in calverify.results)
+ self.assertTrue("Mismatch Organizer" not in calverify.results)
+
+ self.assertTrue("Fix change event" not in calverify.results)
+ self.assertTrue("Fix add event" not in calverify.results)
+ self.assertTrue("Fix add inbox" not in calverify.results)
+ self.assertTrue("Fix remove" not in calverify.results)
+ self.assertTrue("Fix failures" not in calverify.results)
+ self.assertTrue("Auto-Accepts" not in calverify.results)
+
+ sync_token_new1 = (yield (yield self.calendarUnderTest(self.uuid1)).syncToken())
+ sync_token_newl1 = (yield (yield self.calendarUnderTest(self.uuidl1)).syncToken())
+ self.assertEqual(sync_token_old1, sync_token_new1)
+ self.assertEqual(sync_token_oldl1, sync_token_newl1)
+
+
+ @inlineCallbacks
+ def test_fixMismatch(self):
+ """
+ CalVerifyService.doScan with fix for mismatches. Make sure it detects
+ and fixes as much as it can. Make sure sync-token is not changed.
+ """
+
+ sync_token_old1 = (yield (yield self.calendarUnderTest(self.uuid1)).syncToken())
+ sync_token_oldl1 = (yield (yield self.calendarUnderTest(self.uuidl1)).syncToken())
+ self.commit()
+
+ options = {
+ "ical": False,
+ "badcua": False,
+ "mismatch": True,
+ "nobase64": False,
+ "fix": True,
+ "verbose": False,
+ "details": False,
+ "uid": "",
+ "uuid": CalVerifyMismatchTestsBase.uuidl1,
+ "tzid": "",
+ "start": PyCalendarDateTime(now, 1, 1, 0, 0, 0),
+ }
+ output = StringIO()
+ calverify = SchedulingMismatchService(self._sqlCalendarStore, options, output, reactor, config)
+ yield calverify.doAction()
+
+ self.assertEqual(calverify.results["Number of events to process"], 2)
+ self.assertTrue("Missing Attendee" not in calverify.results)
+ self.assertEqual(calverify.results["Mismatch Attendee"], set((
+ ("MISMATCH_ATTENDEE_ICS", self.uuid1, self.uuidl1,),
+ )))
+ self.assertTrue("Missing Organizer" not in calverify.results)
+ self.assertTrue("Mismatch Organizer" not in calverify.results)
+
+ self.assertEqual(calverify.results["Fix change event"], set((
+ (self.uuidl1, "calendar", "MISMATCH_ATTENDEE_ICS",),
+ )))
+
+ self.assertTrue("Fix add event" not in calverify.results)
+
+ self.assertEqual(calverify.results["Fix add inbox"], set((
+ (self.uuidl1, "MISMATCH_ATTENDEE_ICS",),
+ )))
+
+ self.assertTrue("Fix remove" not in calverify.results)
+
+ self.assertEqual(calverify.results["Fix failures"], 0)
+ testResults = sorted(calverify.results["Auto-Accepts"], key=lambda x: x["uid"])
+ self.assertEqual(testResults[0]["path"], "/calendars/__uids__/%s/calendar/mismatched_attendee.ics" % self.uuidl1)
+ self.assertEqual(testResults[0]["uid"], "MISMATCH_ATTENDEE_ICS")
+ self.assertEqual(testResults[0]["start"].getText(), "%s0307T031500" % (now,))
+
+ sync_token_new1 = (yield (yield self.calendarUnderTest(self.uuid1)).syncToken())
+ sync_token_newl1 = (yield (yield self.calendarUnderTest(self.uuidl1)).syncToken())
+ self.assertEqual(sync_token_old1, sync_token_new1)
+ self.assertNotEqual(sync_token_oldl1, sync_token_newl1)
+
+ # Re-scan after changes to make sure there are no errors
+ self.commit()
+ options["fix"] = False
+ options["uuid"] = CalVerifyMismatchTestsBase.uuidl1
+ calverify = SchedulingMismatchService(self._sqlCalendarStore, options, output, reactor, config)
+ yield calverify.doAction()
+
+ self.assertEqual(calverify.results["Number of events to process"], 2)
+ self.assertTrue("Missing Attendee" not in calverify.results)
+ self.assertTrue("Mismatch Attendee" not in calverify.results)
+ self.assertTrue("Missing Organizer" not in calverify.results)
+ self.assertTrue("Mismatch Organizer" not in calverify.results)
+ self.assertTrue("Fix add event" not in calverify.results)
+ self.assertTrue("Fix add inbox" not in calverify.results)
+ self.assertTrue("Fix remove" not in calverify.results)
+ self.assertTrue("Fix failures" not in calverify.results)
+ self.assertTrue("Auto-Accepts" not in calverify.results)
+
+
+
+class CalVerifyDoubleBooked(CalVerifyMismatchTestsBase):
+ """
+ Tests calverify for double-bookings.
+ """
+
+ # No overlap
+ INVITE_NO_OVERLAP_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100303T181216Z
+UID:INVITE_NO_OVERLAP_ICS
+TRANSP:OPAQUE
+SUMMARY:INVITE_NO_OVERLAP_ICS
+DTSTART:%(year)s0307T100000Z
+DURATION:PT1H
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
+ORGANIZER:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n") % {"year": now}
+
+ # Two overlapping
+ INVITE_NO_OVERLAP1_1_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100303T181216Z
+UID:INVITE_NO_OVERLAP1_1_ICS
+TRANSP:OPAQUE
+SUMMARY:INVITE_NO_OVERLAP1_1_ICS
+DTSTART:%(year)s0307T110000Z
+DURATION:PT2H
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
+ORGANIZER:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n") % {"year": now}
+
+ INVITE_NO_OVERLAP1_2_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100303T181216Z
+UID:INVITE_NO_OVERLAP1_2_ICS
+TRANSP:OPAQUE
+SUMMARY:INVITE_NO_OVERLAP1_2_ICS
+DTSTART:%(year)s0307T120000Z
+DURATION:PT1H
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
+ORGANIZER:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n") % {"year": now}
+
+ # Two overlapping with one transparent
+ INVITE_NO_OVERLAP2_1_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100303T181216Z
+UID:INVITE_NO_OVERLAP2_1_ICS
+TRANSP:OPAQUE
+SUMMARY:INVITE_NO_OVERLAP2_1_ICS
+DTSTART:%(year)s0307T140000Z
+DURATION:PT2H
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
+ORGANIZER:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n") % {"year": now}
+
+ INVITE_NO_OVERLAP2_2_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100303T181216Z
+UID:INVITE_NO_OVERLAP2_2_ICS
+SUMMARY:INVITE_NO_OVERLAP2_2_ICS
+DTSTART:%(year)s0307T150000Z
+DURATION:PT1H
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
+ORGANIZER:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+TRANSP:TRANSPARENT
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n") % {"year": now}
+
+ # Two overlapping with one cancelled
+ INVITE_NO_OVERLAP3_1_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100303T181216Z
+UID:INVITE_NO_OVERLAP3_1_ICS
+TRANSP:OPAQUE
+SUMMARY:Ancient event
+DTSTART:%(year)s0307T170000Z
+DURATION:PT2H
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
+ORGANIZER:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n") % {"year": now}
+
+ INVITE_NO_OVERLAP3_2_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100303T181216Z
+UID:INVITE_NO_OVERLAP3_2_ICS
+SUMMARY:INVITE_NO_OVERLAP3_2_ICS
+DTSTART:%(year)s0307T180000Z
+DURATION:PT1H
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
+ORGANIZER:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+STATUS:CANCELLED
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n") % {"year": now}
+
+ # Two overlapping recurring
+ INVITE_NO_OVERLAP4_1_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100303T181216Z
+UID:INVITE_NO_OVERLAP4_1_ICS
+TRANSP:OPAQUE
+SUMMARY:INVITE_NO_OVERLAP4_1_ICS
+DTSTART:%(year)s0308T120000Z
+DURATION:PT2H
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
+ORGANIZER:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+RRULE:FREQ=DAILY;COUNT=3
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n") % {"year": now}
+
+ INVITE_NO_OVERLAP4_2_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100303T181216Z
+UID:INVITE_NO_OVERLAP4_2_ICS
+SUMMARY:INVITE_NO_OVERLAP4_2_ICS
+DTSTART:%(year)s0309T120000Z
+DURATION:PT1H
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
+ORGANIZER:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+RRULE:FREQ=DAILY;COUNT=2
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n") % {"year": now}
+
+ # Two overlapping on one recurrence instance
+ INVITE_NO_OVERLAP5_1_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100303T181216Z
+UID:INVITE_NO_OVERLAP5_1_ICS
+TRANSP:OPAQUE
+SUMMARY:INVITE_NO_OVERLAP5_1_ICS
+DTSTART:%(year)s0312T120000Z
+DURATION:PT2H
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
+ORGANIZER:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+RRULE:FREQ=DAILY;COUNT=3
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n") % {"year": now}
+
+ INVITE_NO_OVERLAP5_2_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100303T181216Z
+UID:INVITE_NO_OVERLAP5_2_ICS
+SUMMARY:INVITE_NO_OVERLAP5_2_ICS
+DTSTART:%(year)s0313T140000Z
+DURATION:PT1H
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
+ORGANIZER:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+RRULE:FREQ=DAILY;COUNT=2
+END:VEVENT
+BEGIN:VEVENT
+CREATED:20100303T181216Z
+UID:INVITE_NO_OVERLAP5_2_ICS
+SUMMARY:INVITE_NO_OVERLAP5_2_ICS
+RECURRENCE-ID:%(year)s0314T140000Z
+DTSTART:%(year)s0314T130000Z
+DURATION:PT1H
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
+ORGANIZER:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n") % {"year": now}
+
+ # Two not overlapping - one all-day
+ INVITE_NO_OVERLAP6_1_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VTIMEZONE
+TZID:America/Los_Angeles
+BEGIN:DAYLIGHT
+DTSTART:20070311T020000
+RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3
+TZNAME:PDT
+TZOFFSETFROM:-0800
+TZOFFSETTO:-0700
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20071104T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11
+TZNAME:PST
+TZOFFSETFROM:-0700
+TZOFFSETTO:-0800
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+CREATED:20100303T181216Z
+UID:INVITE_NO_OVERLAP6_1_ICS
+TRANSP:OPAQUE
+SUMMARY:INVITE_NO_OVERLAP6_1_ICS
+DTSTART;TZID=America/Los_Angeles:%(year)s0320T200000
+DURATION:PT2H
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
+ORGANIZER:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n") % {"year": now}
+
+ INVITE_NO_OVERLAP6_2_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100303T181216Z
+UID:INVITE_NO_OVERLAP6_2_ICS
+TRANSP:OPAQUE
+SUMMARY:INVITE_NO_OVERLAP6_2_ICS
+DTSTART;VALUE=DATE:%(year)s0321
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
+ORGANIZER:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n") % {"year": now}
+
+ # Two overlapping - same organizer and summary
+ INVITE_NO_OVERLAP7_1_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100303T181216Z
+UID:INVITE_NO_OVERLAP7_1_ICS
+TRANSP:OPAQUE
+SUMMARY:INVITE_NO_OVERLAP7_1_ICS
+DTSTART:%(year)s0323T110000Z
+DURATION:PT2H
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
+ORGANIZER:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n") % {"year": now}
+
+ INVITE_NO_OVERLAP7_2_ICS = """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//Apple Inc.//iCal 4.0.1//EN
+CALSCALE:GREGORIAN
+BEGIN:VEVENT
+CREATED:20100303T181216Z
+UID:INVITE_NO_OVERLAP7_2_ICS
+TRANSP:OPAQUE
+SUMMARY:INVITE_NO_OVERLAP7_1_ICS
+DTSTART:%(year)s0323T120000Z
+DURATION:PT1H
+DTSTAMP:20100303T181220Z
+SEQUENCE:2
+ORGANIZER:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:D46F3D71-04B7-43C2-A7B6-6F92F92E61D0
+ATTENDEE:urn:uuid:75EA36BE-F71B-40F9-81F9-CF59BF40CA8F
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n") % {"year": now}
+
+ allEvents = {
+ "invite1.ics" : (INVITE_NO_OVERLAP_ICS, CalVerifyMismatchTestsBase.metadata,),
+ "invite2.ics" : (INVITE_NO_OVERLAP1_1_ICS, CalVerifyMismatchTestsBase.metadata,),
+ "invite3.ics" : (INVITE_NO_OVERLAP1_2_ICS, CalVerifyMismatchTestsBase.metadata,),
+ "invite4.ics" : (INVITE_NO_OVERLAP2_1_ICS, CalVerifyMismatchTestsBase.metadata,),
+ "invite5.ics" : (INVITE_NO_OVERLAP2_2_ICS, CalVerifyMismatchTestsBase.metadata,),
+ "invite6.ics" : (INVITE_NO_OVERLAP3_1_ICS, CalVerifyMismatchTestsBase.metadata,),
+ "invite7.ics" : (INVITE_NO_OVERLAP3_2_ICS, CalVerifyMismatchTestsBase.metadata,),
+ "invite8.ics" : (INVITE_NO_OVERLAP4_1_ICS, CalVerifyMismatchTestsBase.metadata,),
+ "invite9.ics" : (INVITE_NO_OVERLAP4_2_ICS, CalVerifyMismatchTestsBase.metadata,),
+ "invite10.ics" : (INVITE_NO_OVERLAP5_1_ICS, CalVerifyMismatchTestsBase.metadata,),
+ "invite11.ics" : (INVITE_NO_OVERLAP5_2_ICS, CalVerifyMismatchTestsBase.metadata,),
+ "invite12.ics" : (INVITE_NO_OVERLAP6_1_ICS, CalVerifyMismatchTestsBase.metadata,),
+ "invite13.ics" : (INVITE_NO_OVERLAP6_2_ICS, CalVerifyMismatchTestsBase.metadata,),
+ "invite14.ics" : (INVITE_NO_OVERLAP7_1_ICS, CalVerifyMismatchTestsBase.metadata,),
+ "invite15.ics" : (INVITE_NO_OVERLAP7_2_ICS, CalVerifyMismatchTestsBase.metadata,),
+ }
+
+ requirements = {
+ CalVerifyMismatchTestsBase.uuid1 : {
+ "calendar" : allEvents,
+ "inbox" : {},
+ },
+ CalVerifyMismatchTestsBase.uuid2 : {
+ "calendar" : {},
+ "inbox" : {},
+ },
+ CalVerifyMismatchTestsBase.uuid3 : {
+ "calendar" : {},
+ "inbox" : {},
+ },
+ CalVerifyMismatchTestsBase.uuidl1 : {
+ "calendar" : allEvents,
+ "inbox" : {},
+ },
+ }
+
+ @inlineCallbacks
+ def test_scanDoubleBookingOnly(self):
+ """
+ CalVerifyService.doScan without fix for mismatches. Make sure it detects
+ as much as it can. Make sure sync-token is not changed.
+ """
+
+ sync_token_old1 = (yield (yield self.calendarUnderTest(self.uuid1)).syncToken())
+ sync_token_oldl1 = (yield (yield self.calendarUnderTest(self.uuidl1)).syncToken())
+ self.commit()
+
+ options = {
+ "ical": False,
+ "badcua": False,
+ "mismatch": False,
+ "nobase64": False,
+ "double": True,
+ "fix": False,
+ "verbose": False,
+ "details": False,
+ "summary": False,
+ "days": 365,
+ "uid": "",
+ "uuid": self.uuidl1,
+ "tzid": "utc",
+ "start": PyCalendarDateTime(now, 1, 1, 0, 0, 0),
+ }
+ output = StringIO()
+ calverify = DoubleBookingService(self._sqlCalendarStore, options, output, reactor, config)
+ yield calverify.doAction()
+
+ self.assertEqual(calverify.results["Number of events to process"], len(self.requirements[CalVerifyMismatchTestsBase.uuidl1]["calendar"]))
+ self.assertEqual(
+ [(sorted((i.uid1, i.uid2,)), str(i.start),) for i in calverify.results["Double-bookings"]],
+ [
+ (["INVITE_NO_OVERLAP1_1_ICS", "INVITE_NO_OVERLAP1_2_ICS"], "%(year)s0307T120000Z" % {"year": now}),
+ (["INVITE_NO_OVERLAP4_1_ICS", "INVITE_NO_OVERLAP4_2_ICS"], "%(year)s0309T120000Z" % {"year": now}),
+ (["INVITE_NO_OVERLAP4_1_ICS", "INVITE_NO_OVERLAP4_2_ICS"], "%(year)s0310T120000Z" % {"year": now}),
+ (["INVITE_NO_OVERLAP5_1_ICS", "INVITE_NO_OVERLAP5_2_ICS"], "%(year)s0314T130000Z" % {"year": now}),
+ ],
+ )
+ self.assertEqual(calverify.results["Number of double-bookings"], 4)
+ self.assertEqual(calverify.results["Number of unique double-bookings"], 3)
+
+ sync_token_new1 = (yield (yield self.calendarUnderTest(self.uuid1)).syncToken())
+ sync_token_newl1 = (yield (yield self.calendarUnderTest(self.uuidl1)).syncToken())
+ self.assertEqual(sync_token_old1, sync_token_new1)
+ self.assertEqual(sync_token_oldl1, sync_token_newl1)
+
+
+ def test_instance(self):
+ """
+ CalVerifyService.doScan without fix for mismatches. Make sure it detects
+ as much as it can. Make sure sync-token is not changed.
+ """
+
+ s = """BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VTIMEZONE
+TZID:America/Los_Angeles
+BEGIN:DAYLIGHT
+DTSTART:20070311T020000
+RRULE:FREQ=YEARLY;BYDAY=2SU;BYMONTH=3
+TZNAME:PDT
+TZOFFSETFROM:-0800
+TZOFFSETTO:-0700
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20071104T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=11
+TZNAME:PST
+TZOFFSETFROM:-0700
+TZOFFSETTO:-0800
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:4760FF93-C7F8-4EB0-B3E8-0B22A96DB1BC
+DTSTART;TZID=America/Los_Angeles:20130221T170000
+DTEND;TZID=America/Los_Angeles:20130221T180000
+ATTENDEE;CN=Casa Blanca APPLE EMP ONLY (12) DA03 4th;CUTYPE=ROOM;PARTSTAT=
+ ACCEPTED;ROLE=REQ-PARTICIPANT:urn:uuid:366CC7BE-FEF7-4FFF-B713-6B883538A24
+ 9
+ATTENDEE;CN=Mark Chu;CUTYPE=INDIVIDUAL;EMAIL=markchu at apple.com;PARTSTAT=AC
+ CEPTED;ROLE=REQ-PARTICIPANT:urn:uuid:46F9D5D9-08E8-4987-9636-CC796F4093C6
+ATTENDEE;CN=Kristie Phan;CUTYPE=INDIVIDUAL;EMAIL=kristie_phan at apple.com;PA
+ RTSTAT=ACCEPTED:urn:uuid:97E8720F-4364-DBEC-6721-123E9A92B980
+CREATED:20130220T200530Z
+DTSTAMP:20130222T002246Z
+EXDATE:20130228T010000Z
+EXDATE:20130314T000000Z
+EXDATE:20130321T000000Z
+EXDATE:20130327T000000Z
+EXDATE:20130328T000000Z
+EXDATE:20130403T000000Z
+LOCATION:Casa Blanca APPLE EMP ONLY (12) DA03 4th
+ORGANIZER;CN=Kristie Phan;EMAIL=kristie_phan at apple.com;SCHEDULE-STATUS=1.2
+ :urn:uuid:97E8720F-4364-DBEC-6721-123E9A92B980
+RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR;WKST=SU
+SEQUENCE:13
+SUMMARY:ESD Daily Meeting
+END:VEVENT
+END:VCALENDAR
+"""
+ from twistedcaldav.ical import Component
+ c = Component.fromString(s)
+ start = PyCalendarDateTime.getToday()
+ start.setDateOnly(False)
+ end = start.duplicate()
+ end.offsetDay(30)
+ config.MaxAllowedInstances = 3000
+ i = c.expandTimeRanges(end, start, ignoreInvalidInstances=True)
+ print(i)
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/test/test_gateway.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/test/test_gateway.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/test/test_gateway.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import os
import sys
@@ -95,7 +96,7 @@
try:
plist = readPlistFromString(output)
except xml.parsers.expat.ExpatError, e:
- print "Error (%s) parsing (%s)" % (e, output)
+ print("Error (%s) parsing (%s)" % (e, output))
raise
returnValue(plist)
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/upgrade.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/upgrade.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/upgrade.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,6 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
"""
This tool allows any necessary upgrade to complete, then exits.
@@ -38,8 +39,8 @@
def usage(e=None):
if e:
- print e
- print ""
+ print(e)
+ print("")
try:
UpgradeOptions().opt_help()
except SystemExit:
@@ -63,7 +64,7 @@
"""
Command-line options for 'calendarserver_upgrade'
- @ivar upgradeers: a list of L{DirectoryUpgradeer} objects which can identify the
+ @ivar upgraders: a list of L{DirectoryUpgradeer} objects which can identify the
calendars to upgrade, given a directory service. This list is built by
parsing --record and --collection options.
"""
@@ -71,6 +72,7 @@
synopsis = description
optFlags = [
+ ['status', 's', "Check database status and exit."],
['postprocess', 'p', "Perform post-database-import processing."],
['debug', 'D', "Debug logging."],
]
@@ -121,6 +123,8 @@
Service which runs, exports the appropriate records, then stops the reactor.
"""
+ started = False
+
def __init__(self, store, options, output, reactor, config):
super(UpgraderService, self).__init__()
self.store = store
@@ -135,7 +139,13 @@
"""
Immediately stop. The upgrade will have been run before this.
"""
- self.output.write("Upgrade complete, shutting down.\n")
+ # If we get this far the database is OK
+ if self.options["status"]:
+ self.output.write("Database OK.\n")
+ else:
+ self.output.write("Upgrade complete, shutting down.\n")
+ UpgraderService.started = True
+
from twisted.internet import reactor
from twisted.internet.error import ReactorNotRunning
try:
@@ -188,16 +198,29 @@
output.write(logDateString() + ' ' + log.textFromEventDict(event) + "\n")
output.flush()
- setLogLevelForNamespace(None, "debug")
- log.addObserver(onlyUpgradeEvents)
+ if not options["status"]:
+ setLogLevelForNamespace(None, "debug")
+ log.addObserver(onlyUpgradeEvents)
+
+
def customServiceMaker():
customService = CalDAVServiceMaker()
customService.doPostImport = options["postprocess"]
return customService
- utilityMain(options["config"], makeService, reactor, customServiceMaker, verbose=options["debug"])
+ def _patchConfig(config):
+ config.FailIfUpgradeNeeded = options["status"]
+
+ def _onShutdown():
+ if not UpgraderService.started:
+ print("Failed to start service.")
+
+ utilityMain(options["config"], makeService, reactor, customServiceMaker, patchConfig=_patchConfig, onShutdown=_onShutdown, verbose=options["debug"])
+
+
+
def logDateString():
logtime = time.localtime()
Y, M, D, h, m, s = logtime[:6]
@@ -219,3 +242,6 @@
return '-%02d%02d' % (h, m)
else:
return '+%02d%02d' % (h, m)
+
+if __name__ == '__main__':
+ main()
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/util.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/util.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/util.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -81,6 +81,7 @@
# to get a txn in order to create a Work item
notifierFactory = NotifierFactory(
None, config.ServerHostName,
+ config.Notifications.CoalesceSeconds,
)
else:
notifierFactory = None
Modified: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/validcalendardata.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/validcalendardata.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/validcalendardata.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
"""
This tool takes data from stdin and validates it as iCalendar data suitable
@@ -32,8 +33,8 @@
def usage(e=None):
if e:
- print e
- print ""
+ print(e)
+ print("")
try:
ValidOptions().opt_help()
except SystemExit:
@@ -145,9 +146,9 @@
result, message = self.validCalendarData()
if result:
- print "Calendar data OK"
+ print("Calendar data OK")
else:
- print message
+ print(message)
self.reactor.stop()
@@ -167,7 +168,7 @@
if unfixed:
raise InvalidICalendarDataError("Calendar data had unfixable problems:\n %s" % ("\n ".join(unfixed),))
if fixed:
- print "Calendar data had fixable problems:\n %s" % ("\n ".join(fixed),)
+ print("Calendar data had fixable problems:\n %s" % ("\n ".join(fixed),))
except ValueError, e:
result = False
Deleted: CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/warmup.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/warmup.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/calendarserver/tools/warmup.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,187 +0,0 @@
-#!/usr/bin/env python
-
-##
-# Copyright (c) 2006-2013 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-"""
-This tool trawls through the server's data store, reading data.
-
-This is useful for ensuring that any on-demand data format upgrades
-are done.
-
-This tool requires access to the calendar server's configuration and
-data storage.
-"""
-
-import os
-import sys
-import sqlite3
-from getopt import getopt, GetoptError
-from os.path import dirname, abspath
-
-from twistedcaldav.config import ConfigurationError
-from twistedcaldav.resource import isPseudoCalendarCollectionResource,\
- CalendarHomeResource
-from twistedcaldav.static import CalDAVFile
-from twistedcaldav.directory.directory import DirectoryService
-
-from calendarserver.tools.util import loadConfig, getDirectory, dummyDirectoryRecord
-
-class UsageError (StandardError):
- pass
-
-def usage(e=None):
- if e:
- print e
- print ""
-
- name = os.path.basename(sys.argv[0])
- print "usage: %s [options] [input_specifiers]" % (name,)
- print ""
- print "Warm up data store by reading everything once."
- print __doc__
- print "options:"
- print " -h --help: print this help and exit"
- print " -f --config: Specify caldavd.plist configuration path"
- print ""
- print "input specifiers:"
- print " -a --all: add all calendar homes"
- print " -H --home: add a calendar home (and all calendars within it)"
- print " -r --record: add a directory record's calendar home (format: 'recordType:shortName')"
- print " -u --user: add a user's calendar home (shorthand for '-r users:shortName')"
-
- if e:
- sys.exit(64)
- else:
- sys.exit(0)
-
-def main():
- try:
- (optargs, args) = getopt(
- sys.argv[1:], "hf:o:aH:r:u:", [
- "config=",
- "output=",
- "help",
- "all", "home=", "record=", "user=",
- ],
- )
- except GetoptError, e:
- usage(e)
-
- configFileName = None
-
- calendarHomes = set()
- records = set()
- allRecords = False
-
- def checkExists(resource):
- if not resource.exists():
- sys.stderr.write("No such file: %s\n" % (resource.fp.path,))
- sys.exit(1)
-
- for opt, arg in optargs:
- if opt in ("-h", "--help"):
- usage()
-
- elif opt in ("-f", "--config"):
- configFileName = arg
-
- elif opt in ("-a", "--all"):
- allRecords = True
-
- elif opt in ("-H", "--home"):
- path = abspath(arg)
- parent = CalDAVFile(dirname(abspath(path)))
- calendarHome = CalendarHomeResource(arg, parent, dummyDirectoryRecord)
- checkExists(calendarHome)
- calendarHomes.add(calendarHome)
-
- elif opt in ("-r", "--record"):
- try:
- recordType, shortName = arg.split(":", 1)
- if not recordType or not shortName:
- raise ValueError()
- except ValueError:
- sys.stderr.write("Invalid record identifier: %r\n" % (arg,))
- sys.exit(1)
-
- records.add((recordType, shortName))
-
- elif opt in ("-u", "--user"):
- records.add((DirectoryService.recordType_users, arg))
-
- if args:
- usage("Too many arguments: %s" % (" ".join(args),))
-
- if records or allRecords:
- try:
- config = loadConfig(configFileName)
- config.directory = getDirectory()
- except ConfigurationError, e:
- sys.stdout.write("%s\n" % (e,))
- sys.exit(1)
-
- for record in records:
- recordType, shortName = record
- calendarHome = config.directory.calendarHomeForShortName(recordType, shortName)
- if not calendarHome:
- sys.stderr.write("No calendar home found for record: (%s)%s\n" % (recordType, shortName))
- sys.exit(1)
- calendarHomes.add(calendarHome)
-
- if allRecords:
- for record in config.directory.allRecords():
- calendarHome = config.directory.calendarHomeForRecord(record)
- if not calendarHome:
- pass
- else:
- calendarHomes.add(calendarHome)
-
- calendarCollections = set()
-
- for calendarHome in calendarHomes:
- #print calendarHome
- #sys.stdout.write("*")
- readProperties(calendarHome)
-
- for childName in calendarHome.listChildren():
- child = calendarHome.getChild(childName)
- if isPseudoCalendarCollectionResource(child):
- calendarCollections.add(child)
-
- for calendarCollection in calendarCollections:
- try:
- for name, uid, type in calendarCollection.index().indexedSearch(None):
- child = calendarCollection.getChild(name)
-
- #sys.stdout.write("+")
- child._text()
-
- readProperties(child)
-
- except sqlite3.OperationalError:
- # Outbox doesn't live on disk
- if calendarCollection.fp.basename() != "outbox":
- raise
-
-def readProperties(resource):
- #sys.stdout.write("-")
- for qname in resource.deadProperties().list():
- resource.readDeadProperty(qname)
- #sys.stdout.write(".")
-
-if __name__ == "__main__":
- main()
Property changes on: CalendarServer/branches/users/gaya/sharedgroups/conf
___________________________________________________________________
Modified: svn:ignore
- caldavd-dev.plist
+ caldavd-dev.plist
caldavd-apns.plist
caldavd-corpds-ldap.plist.latest
caldavd-included.plist
caldavd-ldap-separate-groupcacher-memcache.plist
caldavd-server.plist
caldavd-with-imip.plist
Modified: CalendarServer/branches/users/gaya/sharedgroups/conf/caldavd-apple.plist
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/conf/caldavd-apple.plist 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/conf/caldavd-apple.plist 2013-03-07 22:42:21 UTC (rev 10867)
@@ -355,30 +355,6 @@
<key>Services</key>
<dict>
- <key>XMPPNotifier</key>
- <dict>
- <!-- XMPP notification service -->
- <key>Service</key>
- <string>twistedcaldav.notify.XMPPNotifierService</string>
- <key>Enabled</key>
- <false/>
-
- <!-- XMPP host and port to contact -->
- <key>Host</key>
- <string>xmpp.host.name</string>
- <key>Port</key>
- <integer>5222</integer>
-
- <!-- Jabber ID and password for the server -->
- <key>JID</key>
- <string>jid at xmpp.host.name/resource</string>
- <key>Password</key>
- <string>password_goes_here</string>
-
- <!-- PubSub service address -->
- <key>ServiceAddress</key>
- <string>pubsub.xmpp.host.name</string>
- </dict>
</dict>
</dict>
Modified: CalendarServer/branches/users/gaya/sharedgroups/conf/caldavd-test.plist
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/conf/caldavd-test.plist 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/conf/caldavd-test.plist 2013-03-07 22:42:21 UTC (rev 10867)
@@ -656,21 +656,13 @@
<key>CoalesceSeconds</key>
<integer>3</integer>
- <key>InternalNotificationHost</key>
- <string>localhost</string>
-
- <key>InternalNotificationPort</key>
- <integer>62309</integer>
-
<key>Services</key>
<dict>
- <key>AMPNotifier</key>
+ <key>AMP</key>
<dict>
- <key>Service</key>
- <string>calendarserver.push.amppush.AMPPushNotifierService</string>
<key>Enabled</key>
- <true/>
+ <false/>
<key>Port</key>
<integer>62311</integer>
<key>EnableStaggering</key>
@@ -679,81 +671,6 @@
<integer>3</integer>
</dict>
- <key>SimpleLineNotifier</key>
- <dict>
- <!-- Simple line notification service (for testing) -->
- <key>Service</key>
- <string>twistedcaldav.notify.SimpleLineNotifierService</string>
- <key>Enabled</key>
- <false/>
- <key>Port</key>
- <integer>62308</integer>
- </dict>
-
- <key>XMPPNotifier</key>
- <dict>
- <!-- XMPP notification service -->
- <key>Service</key>
- <string>twistedcaldav.notify.XMPPNotifierService</string>
- <key>Enabled</key>
- <false/>
-
- <!-- XMPP host and port to contact -->
- <key>Host</key>
- <string>xmpp.host.name</string>
- <key>Port</key>
- <integer>5222</integer>
-
- <!-- Jabber ID and password for the server -->
- <key>JID</key>
- <string>jid at xmpp.host.name/resource</string>
- <key>Password</key>
- <string>password_goes_here</string>
-
- <!-- PubSub service address -->
- <key>ServiceAddress</key>
- <string>pubsub.xmpp.host.name</string>
-
- <!-- Apple-specific config -->
- <key>CalDAV</key>
- <dict>
- <key>APSBundleID</key>
- <string></string>
- <key>SubscriptionURL</key>
- <string></string>
- </dict>
- <key>CardDAV</key>
- <dict>
- <key>APSBundleID</key>
- <string></string>
- <key>SubscriptionURL</key>
- <string></string>
- </dict>
-
- <key>NodeConfiguration</key>
- <dict>
- <key>pubsub#deliver_payloads</key>
- <string>1</string>
- <key>pubsub#persist_items</key>
- <string>1</string>
- </dict>
-
- <!-- Sends a presence notification to XMPP server at this interval (prevents disconnect) -->
- <key>KeepAliveSeconds</key>
- <integer>120</integer>
-
- <!-- Sends a pubsub publish to a particular heartbeat node at this interval -->
- <key>HeartbeatMinutes</key>
- <integer>30</integer>
-
- <!-- List of glob-like expressions defining which XMPP JIDs can converse with the server (for debugging) -->
- <key>AllowedJIDs</key>
- <array>
- <!--
- <string>*.example.com</string>
- -->
- </array>
- </dict>
</dict>
</dict>
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/migration/calendarcommonextra.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/migration/calendarcommonextra.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/migration/calendarcommonextra.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -9,6 +9,7 @@
# Software License Agreement accompanying the package this file is a
# part of. You may not port this file to another platform without
# Apple's written consent.
+from __future__ import print_function
import datetime
import subprocess
@@ -32,7 +33,7 @@
try:
timestamp = datetime.datetime.now().strftime("%b %d %H:%M:%S")
msg = "calendarcommonextra: %s %s" % (timestamp, msg)
- print msg # so it appears in Setup.log
+ print(msg) # so it appears in Setup.log
with open(LOG, 'a') as output:
output.write("%s\n" % (msg,)) # so it appears in our log
except IOError:
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/migration/calendardemotion.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/migration/calendardemotion.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/migration/calendardemotion.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -9,6 +9,7 @@
# Software License Agreement accompanying the package this file is a
# part of. You may not port this file to another platform without
# Apple's written consent.
+from __future__ import print_function
import os
from plistlib import readPlist, writePlist
@@ -30,7 +31,7 @@
writePlist(plistData, plistPath)
except Exception, e:
- print "Unable to disable services in %s: %s" % (plistPath, e)
+ print("Unable to disable services in %s: %s" % (plistPath, e))
if __name__ == '__main__':
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/migration/calendarmigrator.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/migration/calendarmigrator.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/migration/calendarmigrator.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -17,7 +17,7 @@
# Software License Agreement accompanying the package this file is a
# part of. You may not port this file to another platform without
# Apple's written consent.
-
+from __future__ import print_function
from __future__ import with_statement
import datetime
@@ -513,7 +513,7 @@
try:
timestamp = datetime.datetime.now().strftime("%b %d %H:%M:%S")
msg = "calendarmigrator: %s %s" % (timestamp, msg)
- print msg # so it appears in Setup.log
+ print(msg) # so it appears in Setup.log
with open(LOG, 'a') as output:
output.write("%s\n" % (msg,)) # so it appears in our log
except IOError:
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/migration/calendarpromotion.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/migration/calendarpromotion.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/migration/calendarpromotion.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -9,6 +9,7 @@
# Software License Agreement accompanying the package this file is a
# part of. You may not port this file to another platform without
# Apple's written consent.
+from __future__ import print_function
import os
import shutil
@@ -77,7 +78,7 @@
gid = getgrnam(GROUP_NAME).gr_gid
os.chown(dirName, uid, gid)
except Exception, e:
- print "Unable to chown %s: %s" % (dirName, e)
+ print("Unable to chown %s: %s" % (dirName, e))
plistPath = os.path.join(DEST_CONFIG_DIR, CALDAVD_PLIST)
@@ -89,7 +90,7 @@
writePlist(plistData, plistPath)
except Exception, e:
- print "Unable to disable update values in %s: %s" % (plistPath, e)
+ print("Unable to disable update values in %s: %s" % (plistPath, e))
else:
# Copy configuration
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/migration/test/test_migrator.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/migration/test/test_migrator.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/migration/test/test_migrator.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import twistedcaldav.test.util
from contrib.migration.calendarmigrator import (
@@ -1093,7 +1094,7 @@
]
for description, (source, target), paths, expected in info:
- # print "-=-=-=- %s -=-=-=-" % (description,)
+ # print("-=-=-=- %s -=-=-=-" % (description,))
accessor = StubDiskAccessor(paths)
actual = examinePreviousSystem(source, target, diskAccessor=accessor)
self.assertEquals(expected, actual)
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/benchlib.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/benchlib.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/benchlib.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import pickle
from time import time
@@ -192,7 +193,7 @@
msg('dtrace stopped')
for (k, v) in leftOver.items():
if v:
- print 'Extra', k, ':', v
+ print('Extra', k, ':', v)
returnValue(data)
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/benchmark.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/benchmark.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/benchmark.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import sys, os, plistlib
from os.path import dirname
@@ -335,7 +336,7 @@
statistics[name] = {}
parameters = scalingParameters.get(name, [1, 9, 81])
for p in parameters:
- print '%s, parameter=%s' % (name, p)
+ print('%s, parameter=%s' % (name, p))
dtrace = DTraceCollector("io_measure.d", pids)
data = yield measure(host, port, dtrace, p, sampleTime)
statistics[name][p] = data
@@ -446,7 +447,7 @@
try:
options.parseOptions(sys.argv[1:])
except UsageError, e:
- print e
+ print(e)
return 1
if options['debug']:
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/compare.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/compare.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/compare.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import sys
@@ -68,7 +69,7 @@
p = ttest_1samp(second, fmean)[1]
if p >= 0.95:
# rejected the null hypothesis
- print sys.argv[1], 'mean of', fmean, 'differs from', sys.argv[2], 'mean of', smean, '(%2.0f%%)' % (p * 100,)
+ print(sys.argv[1], 'mean of', fmean, 'differs from', sys.argv[2], 'mean of', smean, '(%2.0f%%)' % (p * 100,))
else:
# failed to reject the null hypothesis
- print 'cannot prove means (%s, %s) differ (%2.0f%%)' % (fmean, smean, p * 100,)
+ print('cannot prove means (%s, %s) differ (%2.0f%%)' % (fmean, smean, p * 100,))
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/display-calendar-events.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/display-calendar-events.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/display-calendar-events.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,16 +13,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import eventkitframework as EventKit
from Cocoa import NSDate
store = EventKit.EKEventStore.alloc().init()
calendars = store.calendarsForEntityType_(0)
-print calendars
+print(calendars)
raise SystemExit
predicate = store.predicateForEventsWithStartDate_endDate_calendars_(
NSDate.date(), NSDate.distantFuture(),
[calendars[2]])
-print store.eventsMatchingPredicate_(predicate)
+print(store.eventsMatchingPredicate_(predicate))
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/httpauth.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/httpauth.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/httpauth.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import urlparse, urllib2
@@ -170,8 +171,8 @@
d = agent.request(
'DELETE', 'http://localhost:8008/calendars/users/user01/monkeys3/')
def deleted(response):
- print response.code
- print response.headers
+ print(response.code)
+ print(response.headers)
reactor.stop()
d.addCallback(deleted)
d.addErrback(err)
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/loadtest/ampsim.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/loadtest/ampsim.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/loadtest/ampsim.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -188,4 +188,3 @@
msg(**event)
return {}
-
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/loadtest/ical.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/loadtest/ical.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/loadtest/ical.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,6 +14,7 @@
# limitations under the License.
#
##
+from __future__ import print_function
from caldavclientlibrary.protocol.caldav.definitions import caldavxml
from caldavclientlibrary.protocol.caldav.definitions import csxml
@@ -316,10 +317,10 @@
self._client = client
def initFailed(self, reason):
- print 'XMPP initialization failed', reason
+ print('XMPP initialization failed', reason)
def authFailed(self, reason):
- print 'XMPP Authentication failed', reason
+ print('XMPP Authentication failed', reason)
def handleMessageEventItems(self, iq):
item = iq.firstChildElement().firstChildElement()
@@ -1986,7 +1987,7 @@
formatArgs['success'] = self.success
else:
formatArgs['success'] = self.failure
- print (self.format % formatArgs).encode('utf-8')
+ print((self.format % formatArgs).encode('utf-8'))
def report(self, output):
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/loadtest/population.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/loadtest/population.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/loadtest/population.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,6 +15,7 @@
# limitations under the License.
#
##
+from __future__ import print_function
"""
Tools for generating a population of CalendarServer users based on
@@ -336,10 +337,10 @@
def eventReceived(self, event):
self._times.append(event['duration'])
if len(self._times) == 200:
- print 'mean:', mean(self._times)
- print 'median:', median(self._times)
- print 'stddev:', stddev(self._times)
- print 'mad:', mad(self._times)
+ print('mean:', mean(self._times))
+ print('median:', median(self._times))
+ print('stddev:', stddev(self._times))
+ print('mad:', mad(self._times))
del self._times[:100]
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/loadtest/sim.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/loadtest/sim.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/loadtest/sim.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,6 +15,7 @@
# limitations under the License.
#
##
+from __future__ import print_function
from collections import namedtuple
from os import environ, mkdir
@@ -261,8 +262,8 @@
try:
mkdir(serializationPath)
except OSError:
- print "Unable to create client data serialization directory: %s" % (serializationPath)
- print "Please consult the clientDataSerialization stanza of contrib/performance/loadtest/config.plist"
+ print("Unable to create client data serialization directory: %s" % (serializationPath))
+ print("Please consult the clientDataSerialization stanza of contrib/performance/loadtest/config.plist")
raise
if 'arrival' in config:
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/massupload.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/massupload.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/massupload.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import sys, pickle
@@ -41,7 +42,7 @@
try:
options.parseOptions(sys.argv[1:])
except UsageError, e:
- print e
+ print(e)
return 1
fname = options['filename']
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/report.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/report.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/report.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import sys, pickle
@@ -20,14 +21,14 @@
def main():
if len(sys.argv) < 5:
- print 'Usage: %s <datafile> <benchmark name> <parameter value> <metric> [command]' % (sys.argv[0],)
+ print('Usage: %s <datafile> <benchmark name> <parameter value> <metric> [command]' % (sys.argv[0],))
else:
stat, samples = select(pickle.load(file(sys.argv[1])), *sys.argv[2:5])
if len(sys.argv) == 5:
- print 'Samples'
- print '\t' + '\n\t'.join(map(str, stat.squash(samples)))
- print 'Commands'
- print '\t' + '\n\t'.join(stat.commands)
+ print('Samples')
+ print('\t' + '\n\t'.join(map(str, stat.squash(samples))))
+ print('Commands')
+ print('\t' + '\n\t'.join(stat.commands))
else:
- print getattr(stat, sys.argv[5])(samples, *sys.argv[6:])
+ print(getattr(stat, sys.argv[5])(samples, *sys.argv[6:]))
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/sqlusage/sqlusage.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/sqlusage/sqlusage.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/sqlusage/sqlusage.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
from StringIO import StringIO
from caldavclientlibrary.client.clientsession import CalDAVSession
@@ -127,11 +128,11 @@
# Now loop over sets of events
for count in counts:
- print "Testing count = %d" % (count,)
+ print("Testing count = %d" % (count,))
self.ensureEvents(sessions[0], sessions[0].calendarHref, count)
result = {}
for request in requests:
- print " Test = %s" % (request.label,)
+ print(" Test = %s" % (request.label,))
result[request.label] = request.execute()
self.results[count] = result
@@ -144,7 +145,7 @@
def _printReport(self, title, attr, colFormat):
table = tables.Table()
- print title
+ print(title)
headers = ["Events"] + self.requestLabels
table.addHeader(headers)
formats = [tables.Table.ColumnFormat("%d", tables.Table.ColumnFormat.RIGHT_JUSTIFY)] + \
@@ -155,8 +156,8 @@
table.addRow(row)
os = StringIO()
table.printTable(os=os)
- print os.getvalue()
- print
+ print(os.getvalue())
+ print("")
def ensureEvents(self, session, calendarhref, n):
"""
@@ -175,9 +176,9 @@
def usage(error_msg=None):
if error_msg:
- print error_msg
+ print(error_msg)
- print """Usage: sqlusage.py [options] [FILE]
+ print("""Usage: sqlusage.py [options] [FILE]
Options:
-h Print this help and exit
--server Server hostname
@@ -191,7 +192,7 @@
Description:
This utility will analyze the output of s pg_stat_statement table.
-"""
+""")
if error_msg:
raise ValueError(error_msg)
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/sqlwatch.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/sqlwatch.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/sqlwatch.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import sys, signal, time
@@ -52,20 +53,20 @@
while True:
pids = instancePIDs(directory)
dtrace = DTraceCollector("sql_measure.d", pids)
- print 'Starting'
+ print('Starting')
yield dtrace.start()
- print 'Started'
+ print('Started')
try:
yield waitForInterrupt()
except Stop:
yield dtrace.stop()
break
- print 'Stopping'
+ print('Stopping')
stats = yield dtrace.stop()
for s in stats:
if s.name == 'execute':
s.statements(stats[s])
- print 'Stopped'
+ print('Stopped')
def main():
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/stats.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/stats.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/stats.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import random, time
@@ -190,10 +191,10 @@
if byTime:
header = '%10s %10s %10s %s'
row = '%10.5f %10.5f %10d %s'
- print header % ('TOTAL MS', 'PERCALL MS', 'NCALLS', 'STATEMENT')
+ print(header % ('TOTAL MS', 'PERCALL MS', 'NCALLS', 'STATEMENT'))
for (time, count, statement) in byTime:
time = time / NANO * 1000
- print row % (time, time / count, count, statement)
+ print(row % (time, time / count, count, statement))
def transcript(self, samples):
@@ -470,8 +471,8 @@
total = 0
for k, v in sorted(result.items(), key=lambda x:x[0]):
- print "%d\t%.5f" % (k, float(v)/result[1])
+ print("%d\t%.5f" % (k, float(v)/result[1]))
total += k * v
- print "Average: %.2f" % (float(total) / sum(result.values()),)
+ print("Average: %.2f" % (float(total) / sum(result.values()),))
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/upload.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/upload.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/performance/upload.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import sys
import pickle
@@ -71,13 +72,13 @@
'max': str(max_value),
'min': str(min_value),
}
- print 'uploading', data
+ print('uploading', data)
agent = Agent(reactor)
d = agent.request('POST', url, None, StringProducer(urlencode(data)))
def check(response):
d = readBody(response)
def read(body):
- print 'body', repr(body)
+ print('body', repr(body))
if response.code != 200:
raise Exception("Upload failed: %r" % (response.code,))
d.addCallback(read)
@@ -110,7 +111,7 @@
try:
options.parseOptions(sys.argv[1:])
except UsageError, e:
- print e
+ print(e)
return 1
fname, benchmark, param, statistic = options['statistic'].split(',')
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/anonymous_log.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/anonymous_log.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/anonymous_log.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
from gzip import GzipFile
import getopt
@@ -47,10 +48,10 @@
if not line.startswith("Log"):
line = self.anonymizeLine(line)
- print line,
+ print(line, end="")
except Exception, e:
- print "Exception: %s for %s" % (e, line,)
+ print("Exception: %s for %s" % (e, line,))
raise
def anonymizeLine(self, line):
@@ -108,9 +109,9 @@
def usage(error_msg=None):
if error_msg:
- print error_msg
+ print(error_msg)
- print """Usage: anonymous_log [options] [FILE]
+ print("""Usage: anonymous_log [options] [FILE]
Options:
-h Print this help and exit
@@ -120,7 +121,7 @@
Description:
This utility will anonymize the content of an access log.
-"""
+""")
if error_msg:
raise ValueError(error_msg)
@@ -153,11 +154,11 @@
if arg.endswith("/"):
arg = arg[:-1]
if not os.path.exists(arg):
- print "Path does not exist: '%s'. Ignoring." % (arg,)
+ print("Path does not exist: '%s'. Ignoring." % (arg,))
continue
CalendarServerLogAnalyzer().anonymizeLogFile(arg)
except Exception, e:
sys.exit(str(e))
- print traceback.print_exc()
+ print(traceback.print_exc())
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/dtraceanalyze.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/dtraceanalyze.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/dtraceanalyze.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -16,8 +16,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
+from __future__ import with_statement
-from __future__ import with_statement
import collections
import getopt
import os
@@ -55,7 +56,7 @@
re_matched = re.match("(..) ([^ ]+) \(([^\)]+)\)", line)
if re_matched is None:
- print line
+ print(line)
results = re_matched.groups()
if results[0] == "<-":
self.entering = False
@@ -175,7 +176,7 @@
backstack.pop()
if backstack: backstack.pop()
if indent < 0:
- print "help"
+ print("help")
current_line = current_line.parent if current_line else None
min_indent = min(min_indent, indent)
@@ -229,7 +230,7 @@
def analyze(self, do_stack, no_collapse):
- print "Parsing dtrace output."
+ print("Parsing dtrace output.")
# Parse the trace lines first and look for the start of the call times
lines = []
@@ -254,22 +255,22 @@
self.printTraceDetails(lines, do_stack, no_collapse)
for ctr, title in enumerate(("Sorted by Count", "Sorted by Exclusive", "Sorted by Inclusive",)):
- print title
+ print(title)
self.printCallTimeTotals(ctr)
def printTraceDetails(self, lines, do_stack, no_collapse):
- print "Found %d lines" % (len(lines),)
- print "============================"
- print ""
+ print("Found %d lines" % (len(lines),))
+ print("============================")
+ print("")
self.stack = Dtrace.DtraceStack(lines, no_collapse)
if do_stack:
with file("stacked.txt", "w") as f:
self.stack.prettyPrint(f)
- print "Wrote stack calls to 'stacked.txt'"
- print "============================"
- print ""
+ print("Wrote stack calls to 'stacked.txt'")
+ print("============================")
+ print("")
# Get stats for each call
stats = {}
@@ -285,17 +286,17 @@
else:
last_exit = line.getPartialKey()
- print "Function Call Counts"
- print ""
+ print("Function Call Counts")
+ print("")
table = tables.Table()
table.addHeader(("Count", "Function", "File",))
for key, value in sorted(stats.iteritems(), key=lambda x: x[1][0], reverse=True):
table.addRow(("%d (%d)" % value, key[1], key[0],))
table.printTable()
- print ""
- print "Called By Counts"
- print ""
+ print("")
+ print("Called By Counts")
+ print("")
table = tables.Table()
table.addHeader(("Function", "Caller", "Count",))
for main_key in sorted(self.stack.called_by.keys(), key=lambda x: x[1] + x[0]):
@@ -309,9 +310,9 @@
first = False
table.printTable()
- print ""
- print "Call Into Counts"
- print ""
+ print("")
+ print("Call Into Counts")
+ print("")
table = tables.Table()
table.addHeader(("Function", "Calls", "Count",))
for main_key in sorted(self.stack.call_into.keys(), key=lambda x: x[1] + x[0]):
@@ -324,7 +325,7 @@
))
first = False
table.printTable()
- print ""
+ print("")
def parseCallTimeLine(self, line, index):
@@ -370,13 +371,13 @@
))
table.printTable()
- print ""
+ print("")
def usage(error_msg=None):
if error_msg:
- print error_msg
+ print(error_msg)
- print """Usage: dtraceanalyze [options] FILE
+ print("""Usage: dtraceanalyze [options] FILE
Options:
-h Print this help and exit
--stack Save indented stack to file
@@ -396,7 +397,7 @@
> sudo ./trace.d PID > results.txt
...
> ./dtraceanalyze.py results.txt
-"""
+""")
if error_msg:
raise ValueError(error_msg)
@@ -432,17 +433,17 @@
if not os.path.exists(filepath):
usage("File '%s' does not exist" % (filepath,))
- print "CalendarServer dtrace analysis tool tool"
- print "====================================="
- print ""
+ print("CalendarServer dtrace analysis tool tool")
+ print("=====================================")
+ print("")
if do_stack:
- print "Generating nested stack call file."
+ print("Generating nested stack call file.")
if no_collapse:
- print "Consecutive function calls will not be removed."
+ print("Consecutive function calls will not be removed.")
else:
- print "Consecutive function calls will be removed."
- print "============================"
- print ""
+ print("Consecutive function calls will be removed.")
+ print("============================")
+ print("")
Dtrace(filepath).analyze(do_stack, no_collapse)
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/fakecalendardata.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/fakecalendardata.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/fakecalendardata.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import datetime
import getopt
@@ -116,9 +117,9 @@
def usage(error_msg=None):
if error_msg:
- print error_msg
+ print(error_msg)
- print """Usage: fakecalendardata [options]
+ print("""Usage: fakecalendardata [options]
Options:
-h Print this help and exit
-a Percentage of events that should include attendees
@@ -133,7 +134,7 @@
Description:
This utility will generate fake iCalendar data either into a single .ics
file or into multiple .ics files.
-"""
+""")
if error_msg:
raise ValueError(error_msg)
@@ -206,7 +207,7 @@
vevents = []
for count, (recurring, attendees, date, hour) in enumerate(eventTypes):
- #print recurring, attendees, date, hour
+ #print(recurring, attendees, date, hour)
vevents.append(makeVEVENT(recurring, attendees, date, hour, count+1))
- print calendar_template % {"VEVENTS" : "".join(vevents)}
+ print(calendar_template % {"VEVENTS" : "".join(vevents)})
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/harpoon.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/harpoon.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/harpoon.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,6 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
# Sends SIGTERM to any calendar server child process whose VSIZE exceeds 2GB
# Only for use in a specific environment
@@ -54,9 +55,9 @@
continue
serverProcessCount += 1
if vsize > CUTOFFBYTES:
- print "Killing process %d with VSIZE %d" % (pidNumber, vsize)
+ print("Killing process %d with VSIZE %d" % (pidNumber, vsize))
os.kill(pidNumber, signal.SIGTERM)
numKilled += 1
-print "Examined %d server processes" % (serverProcessCount,)
-print "Killed %d processes" % (numKilled,)
+print("Examined %d server processes" % (serverProcessCount,))
+print("Killed %d processes" % (numKilled,))
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/monitoranalysis.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/monitoranalysis.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/monitoranalysis.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import matplotlib.pyplot as plt
import getopt
@@ -26,7 +27,7 @@
def analyze(fpath, noweekends, startDate=None, endDate=None, title=None):
- print "Analyzing data for %s" % (fpath,)
+ print("Analyzing data for %s" % (fpath,))
data = []
firstDate = None
global initialDate
@@ -77,7 +78,7 @@
if reqs <= 80:
data.append((dtstamp, reqs, resp, lqnon, cpu))
- #print "%s %d %d %d %d" % (dtstamp, reqs, resp, lqnon, cpu)
+ #print("%s %d %d %d %d" % (dtstamp, reqs, resp, lqnon, cpu))
except StopIteration:
break
@@ -93,7 +94,7 @@
dataset.append((title, data,))
- print "Stored %d data points" % (len(data),)
+ print("Stored %d data points" % (len(data),))
def plotListenQBands(data, first, last, xlim, ylim):
@@ -161,7 +162,7 @@
def plot(figure, noshow, nosave, pngDir, xlim, ylim):
- print "Plotting data"
+ print("Plotting data")
plt.figure(figure, figsize=(16, 5 * len(dataset)))
@@ -193,9 +194,9 @@
def usage(error_msg=None):
if error_msg:
- print error_msg
+ print(error_msg)
- print """Usage: monitoranalysis [options] [FILE+]
+ print("""Usage: monitoranalysis [options] [FILE+]
Options:
-h Print this help and exit
-d Directory to save PNGs to
@@ -216,7 +217,7 @@
Description:
This utility will analyze the output of the request monitor tool and
generate some pretty plots of data.
-"""
+""")
if error_msg:
raise ValueError(error_msg)
@@ -273,7 +274,7 @@
count = 1
for name in fnames:
if name.startswith("request.log"):
- print "Found file: %s" % (os.path.join(scanDir, name),)
+ print("Found file: %s" % (os.path.join(scanDir, name),))
trailer = name[len("request.log"):]
if trailer.startswith("."):
trailer = trailer[1:]
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/monitorsplit.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/monitorsplit.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/monitorsplit.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import getopt
import sys
@@ -29,7 +30,7 @@
global outputFile, fileCount, lastWeek
- print "Splitting data for %s" % (fpath,)
+ print("Splitting data for %s" % (fpath,))
f = GzipFile(fpath) if fpath.endswith(".gz") else open(fpath)
for line in f:
if line.startswith("2010/0"):
@@ -48,7 +49,7 @@
outputFile = open(os.path.join(outputDir, "request.log.%s" % (date,)), "w")
fileCount += 1
lastWeek = currentWeek
- print "Changed to week of %s" % (date,)
+ print("Changed to week of %s" % (date,))
output = ["-----\n"]
output.append(line)
@@ -75,9 +76,9 @@
def usage(error_msg=None):
if error_msg:
- print error_msg
+ print(error_msg)
- print """Usage: monitoranalysis [options] FILE+
+ print("""Usage: monitoranalysis [options] FILE+
Options:
-h Print this help and exit
-d Directory to store split files in
@@ -92,7 +93,7 @@
Description:
This utility will analyze the output of the request monitor tool and
generate some pretty plots of data.
-"""
+""")
if error_msg:
raise ValueError(error_msg)
@@ -125,4 +126,4 @@
for arg in args:
split(argPath(arg), outputDir)
- print "Created %d files" % (fileCount,)
+ print("Created %d files" % (fileCount,))
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/netstatus.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/netstatus.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/netstatus.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
"""
Tool to monitor network connection status and track queue sizes and
@@ -80,20 +81,20 @@
else:
pendingq[key] = (timestamp, recv, sendq,)
- print "------------------------"
- print ""
- print time.asctime()
- print "State Total RecvQ SendQ"
+ print("------------------------")
+ print("")
+ print(time.asctime())
+ print("State Total RecvQ SendQ")
for ctr, items in enumerate(stateNames):
- print "%11s %5d %5d %5d" % (items[0], states[ctr][0], states[ctr][1], states[ctr][2])
+ print("%11s %5d %5d %5d" % (items[0], states[ctr][0], states[ctr][1], states[ctr][2]))
- print ""
- print "Source IP Established (secs) RecvQ SendQ"
+ print("")
+ print("Source IP Established (secs) RecvQ SendQ")
for key, value in sorted(pendingq.iteritems(), key=lambda x:x[1]):
startedat, recv, sendq = value
deltatime = timestamp - startedat
if deltatime > 0:
- print "%-20s %3d %5s %5s" % (key, deltatime, recv, sendq,)
+ print("%-20s %3d %5s %5s" % (key, deltatime, recv, sendq,))
sys.stdout.flush()
time.sleep(5)
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/pg_stats_analysis.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/pg_stats_analysis.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/pg_stats_analysis.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import sqlparse
import os
@@ -51,7 +52,7 @@
try:
statements = sqlparse.parse(sql)
except ValueError, e:
- print e
+ print(e)
# Replace any literal values with placeholders
qmark = sqlparse.sql.Token('Operator', '?')
_substitute(statements[0], qmark)
@@ -134,9 +135,9 @@
None,
))
- print "Queries sorted by %s" % (sorttype,)
+ print("Queries sorted by %s" % (sorttype,))
table.printTable()
- print ""
+ print("")
def parseStats(logFilePath, donormlize=True, verbose=False):
@@ -175,20 +176,20 @@
bits = [bit.strip() for bit in bits]
entries.append(bits)
if verbose and divmod(len(entries), 1000)[1] == 0:
- print "%d entries" % (len(entries),)
+ print("%d entries" % (len(entries),))
#if float(bits[COLUMN_total_time]) > 1:
- # print bits[COLUMN_total_time], bits[COLUMN_query]
+ # print(bits[COLUMN_total_time], bits[COLUMN_query])
if verbose:
- print "Read %d entries" % (len(entries,))
+ print("Read %d entries" % (len(entries,)))
sqlStatementsReport(entries)
def usage(error_msg=None):
if error_msg:
- print error_msg
+ print(error_msg)
- print """Usage: pg_stats_analysis.py [options] FILE
+ print("""Usage: pg_stats_analysis.py [options] FILE
Options:
-h Print this help and exit
-v Generate progress information
@@ -199,7 +200,7 @@
Description:
This utility will analyze the output of s pg_stat_statement table.
-"""
+""")
if error_msg:
raise ValueError(error_msg)
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/protocolanalysis.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/protocolanalysis.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/protocolanalysis.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
from gzip import GzipFile
import collections
@@ -319,7 +320,7 @@
try:
self.parseLine(line)
except:
- print "Could not parse line:\n%s" % (line,)
+ print("Could not parse line:\n%s" % (line,))
continue
# Filter method
@@ -480,7 +481,7 @@
self.userInteractionAnalysis(adjustedMethod)
except Exception:
- print "Failed to process line:\n%s" % (line,)
+ print("Failed to process line:\n%s" % (line,))
raise
# Average various items
@@ -942,85 +943,85 @@
self.printInfo(doTabs)
- print "Load Analysis"
+ print("Load Analysis")
self.printHourlyTotals(doTabs, summary)
if not summary:
- print "Client Analysis"
+ print("Client Analysis")
self.printClientTotals(doTabs)
- print "Protocol Analysis Count"
+ print("Protocol Analysis Count")
self.printHourlyByXXXDetails(
self.hourlyByOKMethodCount if self.separate401s else self.hourlyByMethodCount,
doTabs,
)
- print "Protocol Analysis Average Response Time (ms)"
+ print("Protocol Analysis Average Response Time (ms)")
self.printHourlyByXXXDetails(
self.averagedHourlyByOKMethodTime if self.separate401s else self.averagedHourlyByMethodTime,
doTabs,
showAverages=True,
)
- print "Protocol Analysis Total Response Time (ms)"
+ print("Protocol Analysis Total Response Time (ms)")
self.printHourlyByXXXDetails(
self.hourlyByOKMethodTime if self.separate401s else self.hourlyByMethodTime,
doTabs,
showFloatPercent=True,
)
- print "Status Code Analysis"
+ print("Status Code Analysis")
self.printHourlyByXXXDetails(self.hourlyByStatus, doTabs)
- print "Protocol Analysis by Status"
+ print("Protocol Analysis by Status")
self.printXXXMethodDetails(self.statusByMethodCount, doTabs, False)
- print "Cache Analysis"
+ print("Cache Analysis")
self.printHourlyCacheDetails(doTabs)
if len(self.hourlyPropfindByResponseCount):
- print "PROPFIND Calendar response count distribution"
+ print("PROPFIND Calendar response count distribution")
self.printHourlyByXXXDetails(self.hourlyPropfindByResponseCount, doTabs)
if len(self.averagedHourlyByRecipientCount):
- print "Average Recipient Counts"
+ print("Average Recipient Counts")
self.printHourlyByXXXDetails(self.averagedHourlyByRecipientCount, doTabs, showTotals=False)
- print "Queue Depth vs Response Time"
+ print("Queue Depth vs Response Time")
self.printQueueDepthResponseTime(doTabs)
- print "Instance Count Distribution"
+ print("Instance Count Distribution")
self.printInstanceCount(doTabs)
- print "Protocol Analysis by Client"
+ print("Protocol Analysis by Client")
self.printXXXMethodDetails(self.clientIDByMethodCount, doTabs)
if len(self.requestSizeByBucket):
- print "Request size distribution"
+ print("Request size distribution")
self.printHourlyByXXXDetails(self.requestSizeByBucket, doTabs)
if len(self.responseSizeByBucket):
- print "Response size distribution (excluding GET Dropbox)"
+ print("Response size distribution (excluding GET Dropbox)")
self.printHourlyByXXXDetails(self.responseSizeByBucket, doTabs)
if len(self.averageResponseCountByMethod):
- print "Average response count by method"
+ print("Average response count by method")
self.printResponseCounts(doTabs)
if len(self.requestTimeByBucket):
- print "Response time distribution"
+ print("Response time distribution")
self.printHourlyByXXXDetails(self.requestTimeByBucket, doTabs)
- print "URI Counts"
+ print("URI Counts")
self.printURICounts(doTabs)
- #print "User Interaction Counts"
+ #print("User Interaction Counts")
#self.printUserInteractionCounts(doTabs)
- print "User Weights (top 100)"
+ print("User Weights (top 100)")
self.printUserWeights(doTabs)
- #print "User Response times"
+ #print("User Response times")
#self.printUserResponseTimes(doTabs)
def printInfo(self, doTabs):
@@ -1037,7 +1038,7 @@
table.addRow(("Lines Analyzed:", sum(self.linesRead.values()),))
table.printTabDelimitedData() if doTabs else table.printTable()
- print ""
+ print("")
def getHourFromIndex(self, index):
@@ -1112,7 +1113,7 @@
)
table.printTabDelimitedData() if doTabs else table.printTable()
- print ""
+ print("")
def printClientTotals(self, doTabs):
@@ -1145,7 +1146,7 @@
))
table.printTabDelimitedData() if doTabs else table.printTable()
- print ""
+ print("")
def printHourlyByXXXDetails(self, hourlyByXXX, doTabs, showTotals=True, showAverages=False, showFloatPercent=False):
@@ -1235,7 +1236,7 @@
table.addFooter(row)
table.printTabDelimitedData() if doTabs else table.printTable()
- print ""
+ print("")
def printHourlyCacheDetails(self, doTabs):
@@ -1326,7 +1327,7 @@
table.addFooter(row)
table.printTabDelimitedData() if doTabs else table.printTable()
- print ""
+ print("")
def printQueueDepthResponseTime(self, doTabs):
@@ -1347,7 +1348,7 @@
))
table.printTabDelimitedData() if doTabs else table.printTable()
- print ""
+ print("")
def printXXXMethodDetails(self, data, doTabs, verticalTotals=True):
@@ -1383,7 +1384,7 @@
table.addFooter(row)
table.printTabDelimitedData() if doTabs else table.printTable()
- print ""
+ print("")
def printInstanceCount(self, doTabs):
@@ -1412,7 +1413,7 @@
))
table.printTabDelimitedData() if doTabs else table.printTable()
- print ""
+ print("")
def printURICounts(self, doTabs):
@@ -1435,7 +1436,7 @@
))
table.printTabDelimitedData() if doTabs else table.printTable()
- print ""
+ print("")
def printUserWeights(self, doTabs):
@@ -1458,7 +1459,7 @@
))
table.printTabDelimitedData() if doTabs else table.printTable()
- print ""
+ print("")
def printResponseCounts(self, doTabs):
@@ -1480,7 +1481,7 @@
table.addFooter(("Total:", self.averageResponseCountByMethod[" TOTAL"],))
table.printTabDelimitedData() if doTabs else table.printTable()
- print ""
+ print("")
def printUserResponseTimes(self, doTabs):
@@ -1508,7 +1509,7 @@
))
table.printTabDelimitedData() if doTabs else table.printTable()
- print ""
+ print("")
def printUserInteractionCounts(self, doTabs):
table = tables.Table()
@@ -1524,7 +1525,7 @@
# Chop off the "(a):" part.
table.addRow((k[4:], v, safePercent(float(v), total)))
table.printTabDelimitedData() if doTabs else table.printTable()
- print ""
+ print("")
class TablePrinter(object):
@@ -1583,7 +1584,7 @@
table.addFooter(row)
table.printTabDelimitedData() if doTabs else table.printTable()
- print ""
+ print("")
class Differ(TablePrinter):
@@ -1595,24 +1596,24 @@
self.printInfo(doTabs)
- print "Load Analysis Differences"
+ print("Load Analysis Differences")
#self.printLoadAnalysisDetails(doTabs)
self.printHourlyTotals(doTabs)
if not summary:
- print "Client Differences"
+ print("Client Differences")
self.printClientTotals(doTabs)
- print "Protocol Count Differences"
+ print("Protocol Count Differences")
self.printMethodCountDetails(doTabs)
- print "Average Response Time Differences"
+ print("Average Response Time Differences")
self.printMethodTimingDetails("clientByMethodAveragedTime", doTabs)
- print "Total Response Time Differences"
+ print("Total Response Time Differences")
self.printMethodTimingDetails("clientByMethodTotalTime", doTabs)
- print "Average Response Count Differences"
+ print("Average Response Count Differences")
self.printResponseCountDetails(doTabs)
def printInfo(self, doTabs):
@@ -1626,7 +1627,7 @@
table.addRow(("Filtered to user:", self.analyzers[0].filterByUser,))
table.printTabDelimitedData() if doTabs else table.printTable()
- print ""
+ print("")
def printLoadAnalysisDetails(self, doTabs):
@@ -1781,7 +1782,7 @@
table.addFooter(ftr, columnFormats=fmt)
table.printTabDelimitedData() if doTabs else table.printTable()
- print ""
+ print("")
def printClientTotals(self, doTabs):
@@ -1863,7 +1864,7 @@
table.addFooter(footer)
table.printTabDelimitedData() if doTabs else table.printTable()
- print ""
+ print("")
def printMethodCountDetails(self, doTabs):
@@ -1953,9 +1954,9 @@
def usage(error_msg=None):
if error_msg:
- print error_msg
+ print(error_msg)
- print """Usage: protocolanalysis [options] [FILE]
+ print("""Usage: protocolanalysis [options] [FILE]
Options:
-h Print this help and exit
--hours Range of hours (local time) to analyze [0:23]
@@ -1976,7 +1977,7 @@
tabulated statistics. It can also display statistics about the
differences between two logs.
-"""
+""")
if error_msg:
raise ValueError(error_msg)
@@ -2053,7 +2054,7 @@
logs.extend(glob.iglob(arg))
else:
if not os.path.exists(arg):
- print "Path does not exist: '%s'. Ignoring." % (arg,)
+ print("Path does not exist: '%s'. Ignoring." % (arg,))
continue
logs.append(arg)
@@ -2061,7 +2062,7 @@
for log in logs:
if diffMode or not analyzers:
analyzers.append(CalendarServerLogAnalyzer(startHour, endHour, utcoffset, resolution, filterByUser, filterByClient))
- print "Analyzing: %s" % (log,)
+ print("Analyzing: %s" % (log,))
analyzers[-1].analyzeLogFile(log)
if diffMode and len(analyzers) > 1:
@@ -2074,12 +2075,12 @@
again = raw_input("Repeat analysis [y/n]:")
if again.lower()[0] == "n":
break
- print "\n\n\n"
+ print("\n\n\n")
for arg in args:
- print "Analyzing: %s" % (arg,)
+ print("Analyzing: %s" % (arg,))
analyzers[0].analyzeLogFile(arg)
analyzers[0].printAll(doTabDelimited, summary)
except Exception, e:
- print traceback.print_exc()
+ print(traceback.print_exc())
sys.exit(str(e))
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/readStats.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/readStats.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/readStats.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
from StringIO import StringIO
import collections
@@ -72,23 +73,23 @@
def printStat(stats, index, showMethods, topUsers, showAgents):
- print "- " * 40
- print "Server: %s" % (stats["Server"],)
- print datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")
- print "Service Uptime: %s" % (datetime.timedelta(seconds=(int(time.time() - stats["System"]["start time"]))),)
+ print("- " * 40)
+ print("Server: %s" % (stats["Server"],))
+ print(datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S"))
+ print("Service Uptime: %s" % (datetime.timedelta(seconds=(int(time.time() - stats["System"]["start time"]))),))
if stats["System"]["cpu count"] > 0:
- print "Current CPU: %.1f%% (%d CPUs)" % (
+ print("Current CPU: %.1f%% (%d CPUs)" % (
stats["System"]["cpu use"],
stats["System"]["cpu count"],
- )
- print "Current Memory Used: %d bytes (%.1f GB) (%.1f%% of total)" % (
+ ))
+ print("Current Memory Used: %d bytes (%.1f GB) (%.1f%% of total)" % (
stats["System"]["memory used"],
stats["System"]["memory used"] / (1024.0 * 1024 * 1024),
stats["System"]["memory percent"],
- )
+ ))
else:
- print "Current CPU: Unavailable"
- print "Current Memory Used: Unavailable"
+ print("Current CPU: Unavailable")
+ print("Current Memory Used: Unavailable")
print
printRequestSummary(stats)
printHistogramSummary(stats[index], index)
@@ -105,8 +106,8 @@
labels = serverLabels(stats)
- print "- " * 40
- print datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")
+ print("- " * 40)
+ print(datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S"))
times = []
for stat in stats:
@@ -163,10 +164,10 @@
def printFailedStats(message):
- print "- " * 40
- print datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")
- print message
- print
+ print("- " * 40)
+ print(datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S"))
+ print(message)
+ print("")
@@ -209,7 +210,7 @@
os = StringIO()
table.printTable(os=os)
- print os.getvalue()
+ print(os.getvalue())
@@ -274,13 +275,13 @@
os = StringIO()
table.printTable(os=os)
- print os.getvalue()
+ print(os.getvalue())
def printHistogramSummary(stat, index):
- print "%s average response histogram" % (index,)
+ print("%s average response histogram" % (index,))
table = tables.Table()
table.addHeader(
("", "<10ms", "10ms<->100ms", "100ms<->1s", "1s<->10s", "10s<->30s", "30s<->60s", ">60s", "Over 1s", "Over 10s"),
@@ -314,7 +315,7 @@
))
os = StringIO()
table.printTable(os=os)
- print os.getvalue()
+ print(os.getvalue())
@@ -339,7 +340,7 @@
def printMethodCounts(stat):
- print "Method Counts"
+ print("Method Counts")
table = tables.Table()
table.addHeader(
("Method", "Count", "%", "Av. Response", "%", "Total Resp. %"),
@@ -377,7 +378,7 @@
))
os = StringIO()
table.printTable(os=os)
- print os.getvalue()
+ print(os.getvalue())
@@ -397,7 +398,7 @@
def printUserCounts(stat, topUsers):
- print "User Counts"
+ print("User Counts")
table = tables.Table()
table.addHeader(
("User", "Total", "Percentage"),
@@ -419,7 +420,7 @@
))
os = StringIO()
table.printTable(os=os)
- print os.getvalue()
+ print(os.getvalue())
@@ -436,7 +437,7 @@
def printAgentCounts(stat):
- print "User-Agent Counts"
+ print("User-Agent Counts")
table = tables.Table()
table.addHeader(
("User-Agent", "Total", "Percentage"),
@@ -458,7 +459,7 @@
))
os = StringIO()
table.printTable(os=os)
- print os.getvalue()
+ print(os.getvalue())
@@ -475,9 +476,9 @@
def usage(error_msg=None):
if error_msg:
- print error_msg
+ print(error_msg)
- print """Usage: readStats [options]
+ print("""Usage: readStats [options]
Options:
-h Print this help and exit
-s Name of local socket to read from
@@ -495,7 +496,7 @@
This utility will print a summary of statistics read from a
server continuously with the specified delay.
-"""
+""")
if error_msg:
raise ValueError(error_msg)
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/request_monitor.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/request_monitor.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/request_monitor.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
from dateutil.parser import parse as dateparse
from subprocess import Popen, PIPE, STDOUT
@@ -41,7 +42,7 @@
elif output == "Linux":
OS = "Linux"
else:
- print "Unknown OS: %s" % (output,)
+ print("Unknown OS: %s" % (output,))
sys.exit(1)
# Some system commands we need to detect
@@ -65,10 +66,10 @@
VMSTAT = "/usr/bin/vmstat"
enableFreeMem = os.path.exists(VMSTAT)
-sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
+sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
-filenames = ["/var/log/caldavd/access.log",]
+filenames = ["/var/log/caldavd/access.log", ]
debug = False
def listenq():
@@ -79,7 +80,7 @@
stdout=PIPE, stderr=STDOUT,
)
output, _ignore_error = child.communicate()
- ssl = nonssl = 0
+ ssl = nonssl = 0
for line in output.split("\n"):
if line.find("8443") != -1:
ssl = int(line.split("/")[0])
@@ -121,6 +122,8 @@
results[filename].extend(output.splitlines())
return results
+
+
def range(filenames, start, end):
results = collections.defaultdict(list)
for filename in filenames:
@@ -132,6 +135,8 @@
break
return results
+
+
def cpuPerDaemon():
a = {}
child = Popen(
@@ -155,6 +160,7 @@
return ", ".join([v for _ignore_k, v in sorted(a.items(), key=lambda i:i[0])])
+
def cpuidle():
if OS == "OS X":
child = Popen(
@@ -175,6 +181,8 @@
output, _ignore_ = child.communicate()
return output.splitlines()[-2].split()[5]
+
+
def freemem():
try:
if OS == "OS X":
@@ -186,11 +194,11 @@
)
output, _ignore_ = child.communicate()
lines = output.split("\n")
-
+
line = lines[0]
- pageSize = int(line[line.find("page size of")+12:].split()[0])
+ pageSize = int(line[line.find("page size of") + 12:].split()[0])
line = lines[1]
- freeSize = int(line[line.find("Pages free:")+11:].split()[0][:-1])
+ freeSize = int(line[line.find("Pages free:") + 11:].split()[0][:-1])
freed = freeSize * pageSize
return "%d bytes (%.1f GB)" % (freed, freed / (1024.0 * 1024 * 1024),)
elif OS == "Linux":
@@ -202,21 +210,23 @@
)
output, _ignore_ = child.communicate()
lines = output.splitlines()
-
+
line = lines[4]
freed = int(line.split()[0]) * 1024
return "%d bytes (%.1f GB)" % (freed, freed / (1024.0 * 1024 * 1024),)
except Exception, e:
if debug:
- print "freemem failure", e
- print traceback.print_exc()
+ print("freemem failure", e)
+ print(traceback.print_exc())
return "error"
+
+
def parseLine(line):
startPos = line.find("- ")
endPos = line.find(" [")
- userId = line[startPos+2:endPos]
+ userId = line[startPos + 2:endPos]
startPos = endPos + 2
endPos = line.find(']', startPos)
@@ -236,7 +246,7 @@
uri = line[startPos:endPos]
startPos = endPos + 11
- status = int(line[startPos:startPos+3])
+ status = int(line[startPos:startPos + 3])
startPos += 4
endPos = line.find(' ', startPos)
@@ -266,40 +276,46 @@
endPos = line.find(' ', startPos)
extended["or"] = int(line[startPos:endPos])
else:
-
+
items = line[startPos:].split()
extended = dict([item.split('=') for item in items if item.find("=") != -1])
return userId, logTime, method, uri, status, bytes, referer, client, extended
+
+
def safePercent(value, total):
-
+
return value * 100.0 / total if total else 0.0
+
+
def usage():
- print "request_monitor [OPTIONS] [FILENAME]"
- print
- print "FILENAME optional path of access log to monitor [/var/log/caldavd/access.log]"
- print
- print "OPTIONS"
- print "-h print help and exit"
- print "--debug print tracebacks and error details"
- print "--lines N specifies how many lines to tail from access.log (default: 10000)"
- print "--range M:N specifies a range of lines to analyze from access.log (default: all)"
- print "--procs N specifies how many python processes are expected in the log file (default: 80)"
- print "--top N how many long requests to print (default: 10)"
- print "--router analyze a partition server router node"
- print "--worker analyze a partition server worker node"
- print
- print "Version: 5"
+ print("request_monitor [OPTIONS] [FILENAME]")
+ print("")
+ print("FILENAME optional path of access log to monitor [/var/log/caldavd/access.log]")
+ print("")
+ print("OPTIONS")
+ print("-h print help and exit")
+ print("--debug print tracebacks and error details")
+ print("--lines N specifies how many lines to tail from access.log (default: 10000)")
+ print("--range M:N specifies a range of lines to analyze from access.log (default: all)")
+ print("--procs N specifies how many python processes are expected in the log file (default: 80)")
+ print("--top N how many long requests to print (default: 10)")
+ print("--users N how many top users to print (default: 5)")
+ print("--router analyze a partition server router node")
+ print("--worker analyze a partition server worker node")
+ print("")
+ print("Version: 5")
numLines = 10000
numProcs = 80
numTop = 10
+numUsers = 5
lineRange = None
router = False
worker = False
-options, args = getopt.getopt(sys.argv[1:], "h", ["debug", "router", "worker", "lines=", "range=", "procs=", "top="])
+options, args = getopt.getopt(sys.argv[1:], "h", ["debug", "router", "worker", "lines=", "range=", "procs=", "top=", "users="])
for option, value in options:
if option == "-h":
usage()
@@ -318,6 +334,8 @@
numProcs = int(value)
elif option == "--top":
numTop = int(value)
+ elif option == "--users":
+ numUsers = int(value)
if len(args):
filenames = sorted([os.path.expanduser(arg) for arg in args])
@@ -325,21 +343,21 @@
for filename in filenames:
if not os.path.isfile(filename):
- print "Path %s does not exist" % (filename,)
- print
+ print("Path %s does not exist" % (filename,))
+ print("")
usage()
sys.exit(1)
for filename in filenames:
if not os.access(filename, os.R_OK):
- print "Path %s does not exist" % (filename,)
- print
+ print("Path %s does not exist" % (filename,))
+ print("")
usage()
sys.exit(1)
if debug:
- print "Starting: access log files: %s" % (", ".join(filenames),)
- print
+ print("Starting: access log files: %s" % (", ".join(filenames),))
+ print("")
while True:
@@ -367,7 +385,7 @@
totalOver1s = [0, 0]
totalOver10s = [0, 0]
requests = []
- users = { }
+ users = {}
startTime = None
endTime = None
errorCount = 0
@@ -379,35 +397,35 @@
for line in lines[filename]:
if not line or line.startswith("Log"):
continue
-
+
numRequests[filename] += 1
-
+
try:
userId, logTime, method, uri, status, bytes, _ignore_referer, client, extended = parseLine(line)
except Exception, e:
parseErrors += 1
-
+
if debug:
- print "Access log line parse failure", e
- print traceback.print_exc()
- print "---"
- print line
- print "---"
-
+ print("Access log line parse failure", e)
+ print(traceback.print_exc())
+ print("---")
+ print(line)
+ print("---")
+
continue
-
+
logTime = dateparse(logTime, fuzzy=True)
times.append(logTime)
perfile_times[filename].append(logTime)
-
+
if status >= 500:
errorCount += 1
-
+
if uri == "/ischedule":
numServerToServer[filename] += 1
elif uri.startswith("/calendars"):
numProxied[filename] += 1
-
+
outstanding = int(extended['or'])
logId = int(extended['i'] if extended['i'] else 0)
raw = rawCounts.get(logId, 0) + 1
@@ -416,7 +434,7 @@
if outstanding > prevMax:
ids[logId] = outstanding
slotCount[filename] += outstanding
-
+
respTime = float(extended['t'])
wrTime = float(extended.get('t-resp-wr', 0.0))
timeSpent = timesSpent.get(logId, 0.0) + respTime
@@ -425,86 +443,84 @@
totalRespWithoutWRTime[filename] += respTime - wrTime
if respTime > maxRespTime[filename]:
maxRespTime[filename] = respTime
-
+
for index, testTime in enumerate((respTime, respTime - wrTime,)):
if testTime >= 60000.0:
over60s[index] += 1
elif testTime >= 30000.0:
- over30s[index] +=1
+ over30s[index] += 1
elif testTime >= 10000.0:
- over10s[index] +=1
+ over10s[index] += 1
elif testTime >= 1000.0:
- over1s[index] +=1
+ over1s[index] += 1
elif testTime >= 100.0:
- over100ms[index] +=1
+ over100ms[index] += 1
elif testTime >= 10.0:
- over10ms[index] +=1
+ over10ms[index] += 1
else:
- under10ms[index] +=1
+ under10ms[index] += 1
if testTime >= 1000.0:
- totalOver1s[index] +=1
+ totalOver1s[index] += 1
if testTime >= 10000.0:
- totalOver10s[index] +=1
-
-
+ totalOver10s[index] += 1
+
ext = []
for key, value in extended.iteritems():
if key not in ('i', 't'):
if key == "cl":
- value = float(value)/1024
+ value = float(value) / 1024
value = "%.1fKB" % (value,)
key = "req"
ext.append("%s:%s" % (key, value))
ext = ", ".join(ext)
-
+
try:
client = client.split(";")[2]
client = client.strip()
except:
pass
-
+
if userId != "-":
- userStat = users.get(userId, { 'count' : 0, 'clients' : {} })
+ userStat = users.get(userId, {'count' : 0, 'clients' : {}})
userStat['count'] += 1
clientCount = userStat['clients'].get(client, 0)
userStat['clients'][client] = clientCount + 1
users[userId] = userStat
-
+
reqStartTime = logTime - datetime.timedelta(milliseconds=respTime)
- requests.append((respTime, userId, method, bytes/1024.0, ext, client, logId, logTime, reqStartTime))
+ requests.append((respTime, userId, method, bytes / 1024.0, ext, client, logId, logTime, reqStartTime))
-
times.sort()
if len(times) == 0:
- print "No data to analyze"
+ print("No data to analyze")
time.sleep(10)
continue
-
+
totalRequests = sum(numRequests.values())
- print "- " * 40
- print datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S"),
+ print("- " * 40)
+ print(datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S"),)
if enableListenQueue:
q, lqssl, lqnon = listenQueueHistory()
- print "Listenq (ssl+non):", q[0], " (Recent", ", ".join(q[1:]), "Oldest)"
+ print("Listenq (ssl+non):", q[0], " (Recent", ", ".join(q[1:]), "Oldest)")
if enableCpuIdle:
q = idleHistory()
- print "CPU idle %:", q[0], " (Recent", ", ".join(q[1:]), "Oldest)"
+ print("CPU idle %:", q[0], " (Recent", ", ".join(q[1:]), "Oldest)")
if enableFreeMem:
- print "Memory free:", freemem()
- print "CPU Per Daemon:", cpuPerDaemon()
- print
+ print("Memory free:", freemem())
+ print("CPU Per Daemon:", cpuPerDaemon())
+ print("")
table = tables.Table()
table.addHeader(
- ("Instance", "Requests", "Av. Requests", "Av. Response", "Av. Response", "Max. Response", "Slot", "Start", "End", "File Name"),
+ ("Instance", "Requests", "Av. Requests", "Av. Response", "Av. Response", "Max. Response", "Slot", "Start", "End", "File Name"),
)
table.addHeader(
- ( "", "", "per second", "(ms)", "no write(ms)", "(ms)", "Average", "Time", "Time", ""),
+ ("", "", "per second", "(ms)", "no write(ms)", "(ms)", "Average", "Time", "Time", ""),
)
table.setDefaultColumnFormats(
(
- tables.Table.ColumnFormat("%s", tables.Table.ColumnFormat.CENTER_JUSTIFY),
+ tables.Table.ColumnFormat("%s", tables.Table.ColumnFormat.CENTER_JUSTIFY),
tables.Table.ColumnFormat("%d", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
tables.Table.ColumnFormat("%.1f", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
tables.Table.ColumnFormat("%.1f", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
@@ -516,7 +532,7 @@
tables.Table.ColumnFormat("%s", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
)
)
-
+
totalAverage = 0.0
totalResponseTime = 0.0
totalResponseWithoutWRTime = 0.0
@@ -525,14 +541,14 @@
minStartTime = None
maxEndTime = None
for ctr, filename in enumerate(sorted(perfile_times.keys())):
-
+
times = sorted(perfile_times[filename])
startTime = times[0]
minStartTime = startTime if minStartTime is None else min(minStartTime, startTime)
endTime = times[-1]
maxEndTime = endTime if maxEndTime is None else min(maxEndTime, endTime)
-
+
deltaTime = endTime - startTime
avgRequests = float(len(times)) / deltaTime.seconds
@@ -540,16 +556,16 @@
avgResponse = totalRespTime[filename] / len(times)
totalResponseTime += totalRespTime[filename]
-
+
avgResponseWithWR = totalRespWithoutWRTime[filename] / len(times)
totalResponseWithoutWRTime += totalRespWithoutWRTime[filename]
-
+
maxResponseTime = max(maxResponseTime, maxRespTime[filename])
-
+
totalSlots += slotCount[filename]
table.addRow((
- "#%s" % (ctr+1,),
+ "#%s" % (ctr + 1,),
len(times),
avgRequests,
avgResponse,
@@ -560,7 +576,7 @@
endTime,
filename[prefix:],
))
-
+
if len(perfile_times) > 1:
table.addFooter((
"Total:",
@@ -574,25 +590,25 @@
maxEndTime,
"",
))
-
+
os = StringIO()
table.printTable(os=os)
- print os.getvalue()
+ print(os.getvalue())
if enableListenQueue:
lqlatency = (lqssl / avgRequests, lqnon / avgRequests,) if avgRequests else (0.0, 0.0,)
- print " listenq latency (ssl+non): %.1f s %.1f s" % (
+ print(" listenq latency (ssl+non): %.1f s %.1f s" % (
lqlatency[0],
lqlatency[1],
- )
-
+ ))
+
table = tables.Table()
table.addHeader(
- ("", "<10ms", "10ms<->100ms", "100ms<->1s", "1s<->10s", "10s<->30s", "30s<->60s", ">60s", "Over 1s", "Over 10s"),
+ ("", "<10ms", "10ms<->100ms", "100ms<->1s", "1s<->10s", "10s<->30s", "30s<->60s", ">60s", "Over 1s", "Over 10s"),
)
table.setDefaultColumnFormats(
(
- tables.Table.ColumnFormat("%s", tables.Table.ColumnFormat.CENTER_JUSTIFY),
+ tables.Table.ColumnFormat("%s", tables.Table.ColumnFormat.CENTER_JUSTIFY),
tables.Table.ColumnFormat("%d (%.1f%%)", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
tables.Table.ColumnFormat("%d (%.1f%%)", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
tables.Table.ColumnFormat("%d (%.1f%%)", tables.Table.ColumnFormat.RIGHT_JUSTIFY),
@@ -619,44 +635,43 @@
))
os = StringIO()
table.printTable(os=os)
- print os.getvalue()
+ print(os.getvalue())
print
if errorCount:
- print "Number of 500 errors: %d" % (errorCount,)
+ print("Number of 500 errors: %d" % (errorCount,))
if parseErrors:
- print "Number of access log parsing errors: %d" % (parseErrors,)
+ print("Number of access log parsing errors: %d" % (parseErrors,))
if errorCount or parseErrors:
- print
+ print("")
- print "Proc: Peak outstanding: Seconds of processing (number of requests):"
- for l in xrange((numProcs-1)/10 + 1):
+ print("Proc: Peak outstanding: Seconds of processing (number of requests):")
+ for l in xrange((numProcs - 1) / 10 + 1):
base = l * 10
- print "%2d-%2d: " % (base, base+9),
+ print("%2d-%2d: " % (base, base + 9),)
- for i in xrange(base, base+10):
+ for i in xrange(base, base + 10):
try:
r = ids[i]
s = "%1d" % (r,)
except KeyError:
s = "."
- print s,
+ print(s, end="")
- print " ",
+ print(" ", end="")
- for i in xrange(base, base+10):
+ for i in xrange(base, base + 10):
try:
r = timesSpent[i] / 1000
c = rawCounts[i]
- s = "%4.0f(%4d)" % (r,c)
+ s = "%4.0f(%4d)" % (r, c)
except KeyError:
s = " ."
- print s,
+ print(s, end="")
+ print("")
- print
-
- print
- print "Top %d longest (in most recent %d requests):" % (numTop, sum(numRequests.values()),)
+ print("")
+ print("Top %d longest (in most recent %d requests):" % (numTop, sum(numRequests.values()),))
requests.sort()
requests.reverse()
for i in xrange(numTop):
@@ -669,46 +684,44 @@
if _logId == logId and _logTime > reqStartTime and _reqStartTime < logTime:
overlapCount += 1
- print "%7.1fms %-12s %s res:%.1fKB, %s [%s] #%d +%d %s->%s" % (respTime, userId, method, kb, ext, client, logId, overlapCount, reqStartTime.strftime("%H:%M:%S"), logTime.strftime("%H:%M:%S"),)
+ print("%7.1fms %-12s %s res:%.1fKB, %s [%s] #%d +%d %s->%s" % (respTime, userId, method, kb, ext, client, logId, overlapCount, reqStartTime.strftime("%H:%M:%S"), logTime.strftime("%H:%M:%S"),))
"""
- print "%7.1fms %-12s %s res:%.1fKB, %s [%s] #%d %s->%s" % (respTime, userId, method, kb, ext, client, logId, reqStartTime.strftime("%H:%M:%S"), logTime.strftime("%H:%M:%S"),)
+ print("%7.1fms %-12s %s res:%.1fKB, %s [%s] #%d %s->%s" % (respTime, userId, method, kb, ext, client, logId, reqStartTime.strftime("%H:%M:%S"), logTime.strftime("%H:%M:%S"),))
except:
pass
-
-
- print
- print "Top 5 busiest users (in most recent %d requests):" % (totalRequests,)
+ print("")
+ print("Top %d busiest users (in most recent %d requests):" % (numUsers, totalRequests,))
userlist = []
for user, userStat in users.iteritems():
userlist.append((userStat['count'], user, userStat))
userlist.sort()
userlist.reverse()
- for i in xrange(5):
+ for i in xrange(numUsers):
try:
count, user, userStat = userlist[i]
- print "%3d %-12s " % (count, user),
+ print("%3d %-12s " % (count, user), end="")
clientStat = userStat['clients']
clients = clientStat.keys()
if len(clients) == 1:
- print "[%s]" % (clients[0],)
+ print("[%s]" % (clients[0],))
else:
clientList = []
for client in clients:
clientList.append("%s: %d" % (client, clientStat[client]))
- print "[%s]" % ", ".join(clientList)
+ print("[%s]" % ", ".join(clientList))
except:
pass
print
-
+
# lineRange => do loop only once
if lineRange is not None:
break
except Exception, e:
- print "Script failure", e
+ print("Script failure", e)
if debug:
- print traceback.print_exc()
+ print(traceback.print_exc())
time.sleep(10)
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/sortrecurrences.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/sortrecurrences.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/sortrecurrences.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import getopt
import os
@@ -23,9 +24,9 @@
def usage(error_msg=None):
if error_msg:
- print error_msg
+ print(error_msg)
- print """Usage: sortrecurrences FILE
+ print("""Usage: sortrecurrences FILE
Options:
-h Print this help and exit
@@ -35,7 +36,7 @@
Description:
This utility will output a sorted iCalendar component.
-"""
+""")
if error_msg:
raise ValueError(error_msg)
@@ -68,13 +69,13 @@
if arg.endswith("/"):
arg = arg[:-1]
if not os.path.exists(arg):
- print "Path does not exist: '%s'. Ignoring." % (arg,)
+ print("Path does not exist: '%s'. Ignoring." % (arg,))
continue
cal = PyCalendar()
cal.parse(open(arg))
- print str(cal.serialize())
+ print(str(cal.serialize()))
except Exception, e:
sys.exit(str(e))
- print traceback.print_exc()
+ print(traceback.print_exc())
Modified: CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/sqldata_from_path.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/sqldata_from_path.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/contrib/tools/sqldata_from_path.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
"""
Prints out an SQL statement that can be used in an SQL shell against
@@ -27,16 +28,16 @@
def usage(error_msg=None):
if error_msg:
- print error_msg
+ print(error_msg)
- print "sqldata_from_path PATH"
- print
- print "PATH filestore or HTTP path"
- print
- print """Prints out an SQL statement that can be used in an SQL shell against
-an sqlstore database to return the calendar or address data for the provided
-filestore or HTTP path. Path must be a __uids__ path.
-"""
+ print("sqldata_from_path PATH")
+ print("")
+ print("PATH filestore or HTTP path")
+ print("""
+Prints out an SQL statement that can be used in an SQL shell against
+an sqlstore database to return the calendar or address data for the
+provided filestore or HTTP path. Path must be a __uids__ path.
+""")
if error_msg:
raise ValueError(error_msg)
@@ -105,11 +106,11 @@
sqlstrings[datatype]["collection"] = collection
sqlstrings[datatype]["resource"] = resource
- print """select %(object_data)s from %(object_table)s where
+ print("""select %(object_data)s from %(object_table)s where
%(object_name)s = '%(resource)s' and %(object_bind_id)s = (
select %(bind_id)s from %(bind_table)s where
%(bind_name)s = '%(collection)s' and %(bind_home_id)s = (
select RESOURCE_ID from %(home_table)s where OWNER_UID = '%(uid)s'
)
- );""" % sqlstrings[datatype]
+ );""" % sqlstrings[datatype])
Modified: CalendarServer/branches/users/gaya/sharedgroups/setup.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/setup.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/setup.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,6 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import sys
import os
@@ -172,7 +173,7 @@
for script in dist.scripts:
scriptPath = os.path.join(install_scripts, os.path.basename(script))
- print "rewriting %s" % (scriptPath,)
+ print("rewriting %s" % (scriptPath,))
script = []
Deleted: CalendarServer/branches/users/gaya/sharedgroups/support/directorysetup.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/support/directorysetup.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/support/directorysetup.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,302 +0,0 @@
-#!/usr/bin/env python
-#
-##
-# Copyright (c) 2007-2013 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-#
-# ...
-#
-
-
-import getopt
-import os
-import sys
-
-def usage():
- print """Usage: directorysetup [options] init|addUser|disableUser|removeUser <<user>>
-Options:
- -h Print this help and exit
- -n node OpenDirectory node to target (/LDAPv3/127.0.0.1)
- -u uid OpenDirectory Admin user id
- -p pswd OpenDirectory Admin user password
- -c cname OpenDirectory /Computers record name for the calendar server
-
-Description:
-This is a little command line utility to setup a directory server with records
-conforming to the new schema used by the calendar server. It has several "actions":
-
-"init" - this action will modify the computer record for the host calendar server to
-add the new "com.apple.macosxserver.virtualhosts" entry.
-
-"addUser" - modifies a user record to enable use of the calendar server.
-
-"disableUser" - modifies a user record to disable use of the calendar server.
-
-"removeUser" - modifies a user record to prevent use of the calendar server by
- removing any reference to the service.
-
-"""
-
-def initComputerRecord(admin_user, admin_pswd, node, recordname):
- plistdefault = """<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>ReplicaName</key>
- <string>Master</string>
- <key>com.apple.od.role</key>
- <string>master</string>
-</dict>
-</plist>
-"""
- plistdefault = plistdefault.replace('"', '\\"')
- plistdefault = plistdefault.replace('\n', '')
-
- plist_good = """<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
- <dict>
- <key>ReplicaName</key>
- <string>Master</string>
-
- <key>com.apple.od.role</key>
- <string>master</string>
-
- <key>com.apple.macosxserver.virtualhosts</key>
- <dict>
- <key>4F088107-51FD-4DE5-904D-2C0AD9C6C893</key>
- <dict>
- <key>hostname</key>
- <string>foo.apple.com</string>
-
- <key>hostDetails</key>
- <dict>
- <key>http</key>
- <dict>
- <key>port</key>
- <integer>80</integer>
- </dict>
- <key>https</key>
- <dict>
- <key>port</key>
- <integer>443</integer>
- </dict>
- </dict>
-
- <key>serviceType</key>
- <array>
- <string>wiki</string>
- <string>webCalendar</string>
- <string>webMailingList</string>
- </array>
-
- <key>serviceInfo</key>
- <dict>
- <key>webCalendar</key>
- <dict>
- <key>enabled</key>
- <true/>
- <key>urlMask</key>
- <string>%(scheme)s://%(hostname)s:%(port)s/groups/%(name)s/webcalendar</string>
- </dict>
- <key>wiki</key>
- <dict>
- <key>enabled</key>
- <true/>
- <key>urlMask</key>
- <string>%(scheme)s://%(hostname)s:%(port)s/groups/%(name)s/wiki</string>
- </dict>
- <key>webMailingList</key>
- <dict>
- <key>enabled</key>
- <true/>
- <key>urlMask</key>
- <string>%(scheme)s://%(hostname)s:%(port)s/groups/%(name)s/mailinglist</string>
- </dict>
- </dict>
- </dict>
-
- <key>C18C34AC-3D9E-403C-8A33-BFC303F3840E</key>
- <dict>
- <key>hostname</key>
- <string>calendar.apple.com</string>
-
- <key>hostDetails</key>
- <dict>
- <key>http</key>
- <dict>
- <key>port</key>
- <integer>8800</integer>
- </dict>
- <key>https</key>
- <dict>
- <key>port</key>
- <integer>8843</integer>
- </dict>
- </dict>
-
- <key>serviceType</key>
- <array>
- <string>calendar</string>
- </array>
-
- <key>serviceInfo</key>
- <dict>
- <key>calendar</key>
- <dict>
- <key>templates</key>
- <dict>
- <key>principalPath</key>
- <string>/principals/%(type)s/%(name)s</string>
- <key>calendarUserAddresses</key>
- <array>
- <string>%(scheme)s://%(hostname)s:%(port)s/principals/%(type)s/%(name)s</string>
- <string>mailto:%(email)s</string>
- <string>urn:uuid:%(guid)s</string>
- </array>
- </dict>
- </dict>
- </dict>
- </dict>
-
- </dict>
- </dict>
-</plist>
-"""
-
- plist_good = plist_good.replace('"', '\\"')
- plist_good = plist_good.replace('\n', '')
- cmd = "dscl -u %s -P %s %s -create /Computers/%s \"dsAttrTypeStandard:XMLPlist\" \"%s\"" % (admin_user, admin_pswd, node, recordname, plist_good,)
- print cmd
- os.system(cmd)
-
-def getComputerRecordGUID(admin_user, admin_pswd, node, computername):
- # First get the generatedGUID for this computer
- cmd = "dscl -u %s -P %s %s -read /Computers/%s \"dsAttrTypeStandard:GeneratedUID\"" % (admin_user, admin_pswd, node, computername,)
- print cmd
- result = os.popen(cmd, "r")
- for line in result:
- return line[len("GeneratedUID: "):-1]
-
-def addUser(admin_user, admin_pswd, node, computername, username):
-
- uid = getComputerRecordGUID(admin_user, admin_pswd, node, computername)
- servicetag = "%s:%s:calendar" % (uid, "C18C34AC-3D9E-403C-8A33-BFC303F3840E")
-
- cmd = "dscl -u %s -P %s %s -create /Users/%s \"dsAttrTypeStandard:ServicesLocator\" \"%s\"" % (admin_user, admin_pswd, node, username, servicetag,)
- print cmd
- os.system(cmd)
-
-def disableUser(admin_user, admin_pswd, node, computername, username):
-
- uid = getComputerRecordGUID(admin_user, admin_pswd, node, computername)
- servicetag = "%s:%s:calendar:disabled" % (uid, "C18C34AC-3D9E-403C-8A33-BFC303F3840E")
-
- cmd = "dscl -u %s -P %s %s -create /Users/%s \"dsAttrTypeStandard:ServicesLocator\" \"%s\"" % (admin_user, admin_pswd, node, username, servicetag,)
- print cmd
- os.system(cmd)
-
-def removeUser(admin_user, admin_pswd, node, computername, username):
- cmd = "dscl -u %s -P %s %s -delete /Users/%s \"dsAttrTypeStandard:ServicesLocator\"" % (admin_user, admin_pswd, node, username,)
- print cmd
- os.system(cmd)
-
-if __name__ == "__main__":
-
- try:
- options, args = getopt.getopt(sys.argv[1:], "hc:n:p:u:")
-
- node = "/LDAPv3/127.0.0.1"
- admin_user = None
- admin_pswd = None
- computername = None
-
- for option, value in options:
- if option == "-h":
- usage()
- sys.exit(0)
- elif option == "-n":
- node = value
- elif option == "-u":
- admin_user = value
- elif option == "-p":
- admin_pswd = value
- elif option == "-c":
- computername = value
- else:
- print "Unrecognized option: %s" % (option,)
- usage()
- raise ValueError
-
- # Some options are required
- if not admin_user:
- print "A user name must be specified with the -u option"
- if not admin_pswd:
- print "A password must be specified with the -p option"
- if not computername:
- print "A computer record name must be specified with the -c option"
- if not admin_user or not admin_pswd or not computername:
- usage()
- raise ValueError
-
- # Process arguments
- if len(args) == 0:
- print "No arguments given. One of 'init', 'addUser', 'disableUser', 'removeUser' must be present."
- usage()
- raise ValueError
- elif args[0] not in ("init", "addUser", "disableUser", "removeUser"):
- print "Wrong arguments given: %s" % (args[0],)
- usage()
- raise ValueError
-
- if args[0] == "init":
- if len(args) > 1:
- print "Too many arguments given to 'init'"
- usage()
- raise ValueError
- initComputerRecord(admin_user, admin_pswd, node, computername)
- elif args[0] == "addUser":
- if len(args) > 2:
- print "Too many arguments given to 'addUser'"
- usage()
- raise ValueError
- elif len(args) != 2:
- print "'addUser' must have one argument - the user name"
- usage()
- raise ValueError
- addUser(admin_user, admin_pswd, node, computername, args[1])
- elif args[0] == "disableUser":
- if len(args) > 2:
- print "Too many arguments given to 'disableUser'"
- usage()
- raise ValueError
- elif len(args) != 2:
- print "'disableUser' must have one argument - the user name"
- usage()
- raise ValueError
- disableUser(admin_user, admin_pswd, node, computername, args[1])
- elif args[0] == "removeUser":
- if len(args) > 2:
- print "Too many arguments given to 'removeUser'"
- usage()
- raise ValueError
- elif len(args) != 2:
- print "'removeUser' must have one argument - the user name"
- usage()
- raise ValueError
- removeUser(admin_user, admin_pswd, node, computername, args[1])
-
- except Exception, e:
- sys.exit(str(e))
Modified: CalendarServer/branches/users/gaya/sharedgroups/support/version.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/support/version.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/support/version.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,6 +15,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import os
from os.path import dirname, basename
@@ -75,4 +76,4 @@
if __name__ == "__main__":
base_version, comment = version()
- print "%s (%s)" % (base_version, comment)
+ print("%s (%s)" % (base_version, comment))
Modified: CalendarServer/branches/users/gaya/sharedgroups/test
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/test 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/test 2013-03-07 22:42:21 UTC (rev 10867)
@@ -95,11 +95,32 @@
rm -f "${tmp}";
fi;
+search_py ()
+{
+ find . \
+ ! '(' -type d '(' -path '*/.*' -or -name data ')' -prune ')' \
+ -type f -name '*.py' \
+ -print0 \
+ | xargs -0 -n 100 grep "$@";
+}
+
+#tmp="$(mktemp "/tmp/calendarserver_test_flakish.XXXXX")";
+#echo "";
+#echo "Checking for other issues..."
+#search_py 'print *[^(]' | sed 's|#.*||' | grep 'print *[^(]' > "${tmp}" || true;
+#if [ -s "${tmp}" ]; then
+# echo "**** Use of legacy print statement found. ****";
+# cat "${tmp}";
+# exit 1;
+#fi;
+#rm -f "${tmp}";
+
tmp="$(mktemp "/tmp/calendarserver_test_emtpy.XXXXX")";
-find "${wd}" '!' '(' -type d '(' -path '*/.*' -o -name data ')' -prune ')' -type f -size 0 > "${tmp}";
+find "${wd}" '!' '(' -type d '(' -path '*/.*' -or -name data ')' -prune ')' -type f -size 0 > "${tmp}";
if [ -s "${tmp}" ]; then
echo "**** Empty files: ****";
cat "${tmp}";
exit 1;
fi;
rm -f "${tmp}";
+
Modified: CalendarServer/branches/users/gaya/sharedgroups/twext/enterprise/dal/parseschema.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/enterprise/dal/parseschema.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/enterprise/dal/parseschema.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
"""
Parser for SQL schema.
@@ -167,7 +168,7 @@
schema.tableNamed(tableName).insertSchemaRow(rowData)
else:
- print 'unknown type:', stmt.get_type()
+ print('unknown type:', stmt.get_type())
return schema
@@ -438,8 +439,8 @@
else:
expected = False
if not expected:
- print 'UNEXPECTED TOKEN:', repr(val), theColumn
- print self.parens
+ print('UNEXPECTED TOKEN:', repr(val), theColumn)
+ print(self.parens)
import pprint
pprint.pprint(self.parens.tokens)
return 0
Modified: CalendarServer/branches/users/gaya/sharedgroups/twext/enterprise/dal/record.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/enterprise/dal/record.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/enterprise/dal/record.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -190,9 +190,12 @@
@classmethod
@inlineCallbacks
def load(cls, transaction, *primaryKey):
- self = (yield cls.query(transaction,
- cls._primaryKeyComparison(primaryKey)))[0]
- returnValue(self)
+ results = (yield cls.query(transaction,
+ cls._primaryKeyComparison(primaryKey)))
+ if len(results) != 1:
+ raise NoSuchRecord()
+ else:
+ returnValue(results[0])
@classmethod
Modified: CalendarServer/branches/users/gaya/sharedgroups/twext/enterprise/dal/test/test_record.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/enterprise/dal/test/test_record.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/enterprise/dal/test/test_record.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -98,6 +98,16 @@
@inlineCallbacks
+ def test_missingLoad(self):
+ """
+ Try loading an row which doesn't exist
+ """
+ txn = self.pool.connection()
+ yield txn.execSQL("insert into ALPHA values (:1, :2)", [234, "one"])
+ self.assertFailure(TestRecord.load(txn, 456), NoSuchRecord)
+
+
+ @inlineCallbacks
def test_simpleCreate(self):
"""
When a record object is created, a row with matching column values will
Modified: CalendarServer/branches/users/gaya/sharedgroups/twext/enterprise/queue.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/enterprise/queue.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/enterprise/queue.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -97,7 +97,7 @@
from twext.enterprise.dal.syntax import SchemaSyntax, Lock, NamedValue
from twext.enterprise.dal.model import ProcedureCall
-from twext.enterprise.dal.record import Record, fromTable
+from twext.enterprise.dal.record import Record, fromTable, NoSuchRecord
from twisted.python.failure import Failure
from twext.enterprise.dal.model import Table, Schema, SQLType, Constraint
@@ -826,15 +826,19 @@
@inlineCallbacks
def work(txn):
workItemClass = WorkItem.forTable(table)
- workItem = yield workItemClass.load(txn, workID)
- if workItem.group is not None:
- yield NamedLock.acquire(txn, workItem.group)
- # TODO: what if we fail? error-handling should be recorded someplace,
- # the row should probably be marked, re-tries should be triggerable
- # administratively.
- yield workItem.delete()
- # TODO: verify that workID is the primary key someplace.
- yield workItem.doWork()
+ try:
+ workItem = yield workItemClass.load(txn, workID)
+ if workItem.group is not None:
+ yield NamedLock.acquire(txn, workItem.group)
+ # TODO: what if we fail? error-handling should be recorded someplace,
+ # the row should probably be marked, re-tries should be triggerable
+ # administratively.
+ yield workItem.delete()
+ # TODO: verify that workID is the primary key someplace.
+ yield workItem.doWork()
+ except NoSuchRecord:
+ # The record has already been removed
+ pass
return inTransaction(txnFactory, work)
Modified: CalendarServer/branches/users/gaya/sharedgroups/twext/internet/gaiendpoint.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/internet/gaiendpoint.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/internet/gaiendpoint.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
"""
L{getaddrinfo}()-based endpoint
@@ -164,18 +165,18 @@
from twisted.internet.protocol import Factory, Protocol
class HelloGoobye(Protocol, object):
def connectionMade(self):
- print 'Hello!'
+ print('Hello!')
self.transport.loseConnection()
def connectionLost(self, reason):
- print 'Goodbye'
+ print('Goodbye')
class MyFactory(Factory, object):
def buildProtocol(self, addr):
- print 'Building protocol for:', addr
+ print('Building protocol for:', addr)
return HelloGoobye()
def bye(what):
- print 'bye', what
+ print('bye', what)
reactor.stop()
gaie.connect(MyFactory()).addBoth(bye)
reactor.run()
Modified: CalendarServer/branches/users/gaya/sharedgroups/twext/python/_plistlib.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/python/_plistlib.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/python/_plistlib.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,6 +1,8 @@
#
# Added to standard library in Python 2.6 (Mac only in prior versions)
#
+from __future__ import print_function
+
"""plistlib.py -- a tool to generate and parse MacOSX .plist files.
The PropertList (.plist) file format is a simple XML pickle supporting
@@ -50,7 +52,7 @@
Parse Plist example::
pl = readPlist(pathOrFile)
- print pl["aKey"]
+ print(pl["aKey"])
"""
Modified: CalendarServer/branches/users/gaya/sharedgroups/twext/python/log.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/python/log.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/python/log.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
"""
Classes and functions to do granular logging.
@@ -110,7 +111,7 @@
# # In case we add log levels that don't map to pythong logging levels:
# #
# for l in logLevels:
-# print "Trying %s: %s, %s" % (l, l in pythonLogLevelMapping, cmpLogLevels(level, l) <= 0)
+# print("Trying %s: %s, %s" % (l, l in pythonLogLevelMapping, cmpLogLevels(level, l) <= 0))
# if l in pythonLogLevelMapping and cmpLogLevels(level, l) <= 0:
# return pythonLogLevelMapping[l]
#
Modified: CalendarServer/branches/users/gaya/sharedgroups/twext/python/memcacheclient.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/python/memcacheclient.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/python/memcacheclient.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+from __future__ import print_function
"""
client module for memcached (memory cache daemon)
@@ -319,7 +320,7 @@
for i in range(Client._SERVER_RETRIES):
server = self.buckets[serverhash % len(self.buckets)]
if server.connect():
- #print "(using server %s)" % server,
+ #print("(using server %s)" % server, end="")
return server, key
serverhash = serverHashFunction(str(serverhash) + str(i))
log.error("Memcacheclient _get_server( ) failed to connect")
@@ -1310,9 +1311,9 @@
return doctest.testmod(memcacheclient, globs=globs)
if __name__ == "__main__":
- print "Testing docstrings..."
+ print("Testing docstrings...")
_doctest()
- print "Running tests:"
+ print("Running tests:")
print
serverList = [["127.0.0.1:11211"]]
if '--do-unix' in sys.argv:
@@ -1326,14 +1327,14 @@
return "%s (%s)" % (val, type(val))
return "%s" % val
def test_setget(key, val):
- print "Testing set/get {'%s': %s} ..." % (to_s(key), to_s(val)),
+ print("Testing set/get {'%s': %s} ..." % (to_s(key), to_s(val)), end="")
mc.set(key, val)
newval = mc.get(key)
if newval == val:
- print "OK"
+ print("OK")
return 1
else:
- print "FAIL"
+ print("FAIL")
return 0
@@ -1350,107 +1351,107 @@
test_setget("a_string", "some random string")
test_setget("an_integer", 42)
if test_setget("long", long(1<<30)):
- print "Testing delete ...",
+ print("Testing delete ...", end="")
if mc.delete("long"):
- print "OK"
+ print("OK")
else:
- print "FAIL"
- print "Testing get_multi ...",
- print mc.get_multi(["a_string", "an_integer"])
+ print("FAIL")
+ print("Testing get_multi ...", end="")
+ print(mc.get_multi(["a_string", "an_integer"]))
- print "Testing get(unknown value) ...",
- print to_s(mc.get("unknown_value"))
+ print("Testing get(unknown value) ...", end="")
+ print(to_s(mc.get("unknown_value")))
f = FooStruct()
test_setget("foostruct", f)
- print "Testing incr ...",
+ print("Testing incr ...", end="")
x = mc.incr("an_integer", 1)
if x == 43:
- print "OK"
+ print("OK")
else:
- print "FAIL"
+ print("FAIL")
- print "Testing decr ...",
+ print("Testing decr ...", end="")
x = mc.decr("an_integer", 1)
if x == 42:
- print "OK"
+ print("OK")
else:
- print "FAIL"
+ print("FAIL")
# sanity tests
- print "Testing sending spaces...",
+ print("Testing sending spaces...", end="")
try:
x = mc.set("this has spaces", 1)
except Client.MemcachedKeyCharacterError, msg:
- print "OK"
+ print("OK")
else:
- print "FAIL"
+ print("FAIL")
- print "Testing sending control characters...",
+ print("Testing sending control characters...", end="")
try:
x = mc.set("this\x10has\x11control characters\x02", 1)
except Client.MemcachedKeyCharacterError, msg:
- print "OK"
+ print("OK")
else:
- print "FAIL"
+ print("FAIL")
- print "Testing using insanely long key...",
+ print("Testing using insanely long key...", end="")
try:
x = mc.set('a'*SERVER_MAX_KEY_LENGTH + 'aaaa', 1)
except Client.MemcachedKeyLengthError, msg:
- print "OK"
+ print("OK")
else:
- print "FAIL"
+ print("FAIL")
- print "Testing sending a unicode-string key...",
+ print("Testing sending a unicode-string key...", end="")
try:
x = mc.set(u'keyhere', 1)
except Client.MemcachedStringEncodingError, msg:
- print "OK",
+ print("OK", end="")
else:
- print "FAIL",
+ print("FAIL", end="")
try:
x = mc.set((u'a'*SERVER_MAX_KEY_LENGTH).encode('utf-8'), 1)
except:
- print "FAIL",
+ print("FAIL", end="")
else:
- print "OK",
+ print("OK", end="")
import pickle
s = pickle.loads('V\\u4f1a\np0\n.')
try:
x = mc.set((s*SERVER_MAX_KEY_LENGTH).encode('utf-8'), 1)
except Client.MemcachedKeyLengthError:
- print "OK"
+ print("OK")
else:
- print "FAIL"
+ print("FAIL")
- print "Testing using a value larger than the memcached value limit...",
+ print("Testing using a value larger than the memcached value limit...", end="")
x = mc.set('keyhere', 'a'*SERVER_MAX_VALUE_LENGTH)
if mc.get('keyhere') == None:
- print "OK",
+ print("OK", end="")
else:
- print "FAIL",
+ print("FAIL", end="")
x = mc.set('keyhere', 'a'*SERVER_MAX_VALUE_LENGTH + 'aaa')
if mc.get('keyhere') == None:
- print "OK"
+ print("OK")
else:
- print "FAIL"
+ print("FAIL")
- print "Testing set_multi() with no memcacheds running",
+ print("Testing set_multi() with no memcacheds running", end="")
mc.disconnect_all()
errors = mc.set_multi({'keyhere' : 'a', 'keythere' : 'b'})
if errors != []:
- print "FAIL"
+ print("FAIL")
else:
- print "OK"
+ print("OK")
- print "Testing delete_multi() with no memcacheds running",
+ print("Testing delete_multi() with no memcacheds running", end="")
mc.disconnect_all()
ret = mc.delete_multi({'keyhere' : 'a', 'keythere' : 'b'})
if ret != 1:
- print "FAIL"
+ print("FAIL")
else:
- print "OK"
+ print("OK")
# vim: ts=4 sw=4 et :
Modified: CalendarServer/branches/users/gaya/sharedgroups/twext/web2/dav/resource.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/web2/dav/resource.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/web2/dav/resource.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -22,6 +22,7 @@
#
# DRI: Wilfredo Sanchez, wsanchez at apple.com
##
+from __future__ import print_function
"""
WebDAV resources.
@@ -759,7 +760,7 @@
)[2].append((resource, url))
# Now determine whether each ace satisfies privileges
- #print aclmap
+ #print(aclmap)
for items in aclmap.itervalues():
checked = (yield self.checkACLPrivilege(
request, items[0], items[1], privileges, inherited_aces
Modified: CalendarServer/branches/users/gaya/sharedgroups/twext/web2/fileupload.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/web2/fileupload.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/web2/fileupload.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -21,7 +21,7 @@
# SOFTWARE.
#
##
-from __future__ import generators
+from __future__ import print_function
import re
from zope.interface import implements
@@ -74,7 +74,7 @@
line = defer.waitForDeferred(line)
yield line
line = line.getResult()
- #print "GOT", line
+ #print("GOT", line)
if not line.endswith('\r\n'):
if line == "":
raise MimeFormatError("Unexpected end of stream.")
@@ -194,7 +194,7 @@
return d
def _readFirstBoundary(self):
- #print "_readFirstBoundary"
+ #print("_readFirstBoundary")
line = self.stream.readline(size=1024)
if isinstance(line, defer.Deferred):
line = defer.waitForDeferred(line)
@@ -209,7 +209,7 @@
_readFirstBoundary = defer.deferredGenerator(_readFirstBoundary)
def _readBoundaryLine(self):
- #print "_readBoundaryLine"
+ #print("_readBoundaryLine")
line = self.stream.readline(size=1024)
if isinstance(line, defer.Deferred):
line = defer.waitForDeferred(line)
@@ -227,7 +227,7 @@
_readBoundaryLine = defer.deferredGenerator(_readBoundaryLine)
def _doReadHeaders(self, morefields):
- #print "_doReadHeaders", morefields
+ #print("_doReadHeaders", morefields)
if not morefields:
return None
return _readHeaders(self.stream)
@@ -392,7 +392,7 @@
log = Logger()
d.addErrback(log.err)
def pr(s):
- print s
+ print(s)
d.addCallback(pr)
Modified: CalendarServer/branches/users/gaya/sharedgroups/twext/web2/http_headers.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/web2/http_headers.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/web2/http_headers.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,5 +1,5 @@
# -*- test-case-name: twext.web2.test.test_http_headers -*-
-# #
+##
# Copyright (c) 2008 Twisted Matrix Laboratories.
# Copyright (c) 2010-2013 Apple Computer, Inc. All rights reserved.
#
@@ -21,7 +21,8 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
-# #
+##
+from __future__ import print_function
"""
HTTP header representation, parsing, and serialization.
@@ -100,7 +101,7 @@
try:
for p in parser:
- # print "Parsing %s: %s(%s)" % (name, repr(p), repr(h))
+ # print("Parsing %s: %s(%s)" % (name, repr(p), repr(h)))
header = p(header)
# if isinstance(h, types.GeneratorType):
# h=list(h)
@@ -125,7 +126,7 @@
generator = self.HTTPGenerators.get(name, None)
if generator is None:
- # print self.generators
+ # print(self.generators)
raise ValueError("No header generator for header '%s', either add one or use setHeaderRaw." % (name,))
for g in generator:
Modified: CalendarServer/branches/users/gaya/sharedgroups/twext/web2/server.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/web2/server.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/web2/server.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -22,6 +22,7 @@
# SOFTWARE.
#
##
+from __future__ import print_function
"""
This is a web-server which integrates with the twisted.internet
@@ -297,7 +298,7 @@
else:
self.prepath = []
self.postpath = path
- #print "_parseURL", self.uri, (self.uri, self.scheme, self.host, self.path, self.params, self.querystring)
+ #print("_parseURL", self.uri, (self.uri, self.scheme, self.host, self.path, self.params, self.querystring))
def _schemeFromPort(self, port):
"""
Modified: CalendarServer/branches/users/gaya/sharedgroups/twext/web2/test/test_client.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/web2/test/test_client.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/web2/test/test_client.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,5 +1,6 @@
# Copyright (c) 2001-2007 Twisted Matrix Laboratories.
# See LICENSE for details.
+from __future__ import print_function
"""
Tests for HTTP client.
@@ -393,7 +394,7 @@
req = http.ClientRequest('GET', '/', None, None)
def gotResp(r):
- print r
+ print(r)
d = cxn.client.submitRequest(req).addCallback(gotResp)
Modified: CalendarServer/branches/users/gaya/sharedgroups/twext/who/__init__.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/who/__init__.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/who/__init__.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,3 +1,4 @@
+# -*- test-case-name: twext.who.test -*-
##
# Copyright (c) 2013 Apple Inc. All rights reserved.
#
Added: CalendarServer/branches/users/gaya/sharedgroups/twext/who/aggregate.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/who/aggregate.py (rev 0)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/who/aggregate.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,91 @@
+# -*- test-case-name: twext.who.test.test_aggregate -*-
+##
+# Copyright (c) 2006-2013 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+"""
+Directory service which aggregates multiple directory services.
+"""
+
+__all__ = [
+ "DirectoryService",
+ "DirectoryRecord",
+]
+
+from itertools import chain
+
+from twisted.internet.defer import gatherResults, FirstError
+
+from twext.who.idirectory import DirectoryConfigurationError
+from twext.who.idirectory import IDirectoryService
+from twext.who.index import DirectoryService as BaseDirectoryService
+from twext.who.index import DirectoryRecord
+from twext.who.util import ConstantsContainer
+
+
+class DirectoryService(BaseDirectoryService):
+ """
+ Aggregate directory service.
+ """
+
+ def __init__(self, realmName, services):
+ recordTypes = set()
+
+ for service in services:
+ if not IDirectoryService.implementedBy(service.__class__):
+ raise ValueError("Not a directory service: %s" % (service,))
+
+ for recordType in service.recordTypes():
+ if recordType in recordTypes:
+ raise DirectoryConfigurationError(
+ "Aggregated services may not vend the same record type: %s"
+ % (recordType,)
+ )
+ recordTypes.add(recordType)
+
+ BaseDirectoryService.__init__(self, realmName)
+
+ self._services = tuple(services)
+
+
+ @property
+ def services(self):
+ return self._services
+
+
+ @property
+ def recordType(self):
+ if not hasattr(self, "_recordType"):
+ self._recordType = ConstantsContainer(chain(*tuple(
+ s.recordTypes()
+ for s in self.services
+ )))
+ return self._recordType
+
+
+ def recordsFromExpression(self, expression, records=None):
+ ds = []
+ for service in self.services:
+ d = service.recordsFromExpression(expression, records)
+ ds.append(d)
+
+ def unwrapFirstError(f):
+ f.trap(FirstError)
+ return f.value.subFailure
+
+ d = gatherResults(ds, consumeErrors=True)
+ d.addCallback(lambda results: chain(*results))
+ d.addErrback(unwrapFirstError)
+ return d
Modified: CalendarServer/branches/users/gaya/sharedgroups/twext/who/directory.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/who/directory.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/who/directory.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,3 +1,4 @@
+# -*- test-case-name: twext.who.test.test_directory -*-
##
# Copyright (c) 2006-2013 Apple Inc. All rights reserved.
#
@@ -33,8 +34,8 @@
from twext.who.idirectory import QueryNotSupportedError, NotAllowedError
from twext.who.idirectory import FieldName, RecordType
from twext.who.idirectory import Operand
-from twext.who.idirectory import DirectoryQueryMatchExpression
from twext.who.idirectory import IDirectoryService, IDirectoryRecord
+from twext.who.expression import MatchExpression
from twext.who.util import uniqueResult, describe
@@ -63,7 +64,7 @@
def recordTypes(self):
- return succeed(self.recordType.iterconstants())
+ return self.recordType.iterconstants()
def recordsFromExpression(self, expression, records=None):
@@ -114,36 +115,43 @@
def recordsWithFieldValue(self, fieldName, value):
- return self.recordsFromExpression(DirectoryQueryMatchExpression(fieldName, value))
+ return self.recordsFromExpression(MatchExpression(fieldName, value))
+
@inlineCallbacks
def recordWithUID(self, uid):
returnValue(uniqueResult((yield self.recordsWithFieldValue(FieldName.uid, uid))))
+
@inlineCallbacks
def recordWithGUID(self, guid):
returnValue(uniqueResult((yield self.recordsWithFieldValue(FieldName.guid, guid))))
+
def recordsWithRecordType(self, recordType):
return self.recordsWithFieldValue(FieldName.recordType, recordType)
+
@inlineCallbacks
def recordWithShortName(self, recordType, shortName):
returnValue(uniqueResult((yield self.recordsFromQuery((
- DirectoryQueryMatchExpression(FieldName.recordType, recordType),
- DirectoryQueryMatchExpression(FieldName.shortNames, shortName ),
+ MatchExpression(FieldName.recordType, recordType),
+ MatchExpression(FieldName.shortNames, shortName ),
)))))
+
def recordsWithEmailAddress(self, emailAddress):
return self.recordsWithFieldValue(FieldName.emailAddresses, emailAddress)
+
def updateRecords(self, records, create=False):
for record in records:
- raise NotAllowedError("Record updates not allowed.")
+ return fail(NotAllowedError("Record updates not allowed."))
+
def removeRecords(self, uids):
for uid in uids:
- raise NotAllowedError("Record removal not allowed.")
+ return fail(NotAllowedError("Record removal not allowed."))
Added: CalendarServer/branches/users/gaya/sharedgroups/twext/who/expression.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/who/expression.py (rev 0)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/who/expression.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,96 @@
+# -*- test-case-name: twext.who.test.test_expression -*-
+##
+# Copyright (c) 2013 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+"""
+Directory query expressions.
+"""
+
+__all__ = [
+ "MatchType",
+ "MatchFlags",
+ "MatchExpression",
+]
+
+from twisted.python.constants import Names, NamedConstant
+from twisted.python.constants import Flags, FlagConstant
+
+
+
+##
+# Match expression
+##
+
+
+
+class MatchType(Names):
+ """
+ Query match types.
+ """
+ equals = NamedConstant()
+ startsWith = NamedConstant()
+ contains = NamedConstant()
+
+ equals.description = "equals"
+ startsWith.description = "starts with"
+ contains.description = "contains"
+
+
+
+class MatchFlags(Flags):
+ """
+ Match expression flags.
+ """
+ NOT = FlagConstant()
+ NOT.description = "not"
+
+ caseInsensitive = FlagConstant()
+ caseInsensitive.description = "case insensitive"
+
+
+
+class MatchExpression(object):
+ """
+ Query for a matching value in a given field.
+
+ @ivar fieldName: a L{NamedConstant} specifying the field
+ @ivar fieldValue: a text value to match
+ @ivar matchType: a L{NamedConstant} specifying the match algorythm
+ @ivar flags: L{NamedConstant} specifying additional options
+ """
+
+ def __init__(self, fieldName, fieldValue, matchType=MatchType.equals, flags=None):
+ self.fieldName = fieldName
+ self.fieldValue = fieldValue
+ self.matchType = matchType
+ self.flags = flags
+
+ def __repr__(self):
+ def describe(constant):
+ return getattr(constant, "description", str(constant))
+
+ if self.flags is None:
+ flags = ""
+ else:
+ flags = " (%s)" % (describe(self.flags),)
+
+ return "<%s: %r %s %r%s>" % (
+ self.__class__.__name__,
+ describe(self.fieldName),
+ describe(self.matchType),
+ describe(self.fieldValue),
+ flags
+ )
Modified: CalendarServer/branches/users/gaya/sharedgroups/twext/who/idirectory.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/who/idirectory.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/who/idirectory.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,3 +1,4 @@
+# -*- test-case-name: twext.who.test -*-
##
# Copyright (c) 2006-2013 Apple Inc. All rights reserved.
#
@@ -20,6 +21,7 @@
__all__ = [
"DirectoryServiceError",
+ "DirectoryConfigurationError",
"DirectoryAvailabilityError",
"UnknownRecordTypeError",
"QueryNotSupportedError",
@@ -28,10 +30,7 @@
"RecordType",
"FieldName",
- "MatchType",
"Operand",
- "QueryFlags",
- "DirectoryQueryMatchExpression",
"IDirectoryService",
"IDirectoryRecord",
@@ -40,7 +39,6 @@
from zope.interface import Attribute, Interface
from twisted.python.constants import Names, NamedConstant
-from twisted.python.constants import Flags, FlagConstant
@@ -53,6 +51,11 @@
Directory service generic error.
"""
+class DirectoryConfigurationError(DirectoryServiceError):
+ """
+ Directory configurtion error.
+ """
+
class DirectoryAvailabilityError(DirectoryServiceError):
"""
Directory not available.
@@ -126,20 +129,6 @@
-class MatchType(Names):
- """
- Query match types.
- """
- equals = NamedConstant()
- startsWith = NamedConstant()
- contains = NamedConstant()
-
- equals.description = "equals"
- startsWith.description = "starts with"
- contains.description = "contains"
-
-
-
class Operand(Names):
OR = NamedConstant()
AND = NamedConstant()
@@ -149,53 +138,6 @@
-class QueryFlags(Flags):
- """
- Query flags.
- """
- NOT = FlagConstant()
- NOT.description = "not"
-
- caseInsensitive = FlagConstant()
- caseInsensitive.description = "case insensitive"
-
-
-
-class DirectoryQueryMatchExpression(object):
- """
- Query for a matching value in a given field.
-
- @ivar fieldName: a L{NamedConstant} specifying the field
- @ivar fieldValue: a text value to match
- @ivar matchType: a L{NamedConstant} specifying the match algorythm
- @ivar flags: L{NamedConstant} specifying additional options
- """
-
- def __init__(self, fieldName, fieldValue, matchType=MatchType.equals, flags=None):
- self.fieldName = fieldName
- self.fieldValue = fieldValue
- self.matchType = matchType
- self.flags = flags
-
- def __repr__(self):
- def describe(constant):
- return getattr(constant, "description", str(constant))
-
- if self.flags is None:
- flags = ""
- else:
- flags = " (%s)" % (self.flags,)
-
- return "<%s: %r %s %r%s>" % (
- self.__class__.__name__,
- describe(self.fieldName),
- describe(self.matchType),
- describe(self.fieldValue),
- flags
- )
-
-
-
##
# Interfaces
##
@@ -219,16 +161,26 @@
def recordTypes():
"""
- @return: a deferred iterable of L{NamedConstant}s denoting the
- record types that are kept in this directory.
+ @return: an iterable of L{NamedConstant}s denoting the record
+ types that are kept in this directory.
"""
+ def recordsFromExpression(self, expression):
+ """
+ Find records matching an expression.
+ @param expression: an expression to apply
+ @type expression: L{object}
+ @return: a deferred iterable of matching L{IDirectoryRecord}s.
+ @raises: L{QueryNotSupportedError} if the expression is not
+ supported by this directory service.
+ """
+
def recordsFromQuery(expressions, operand=Operand.AND):
"""
- Find records matching a query consisting of an iterable of
+ Find records by composing a query consisting of an iterable of
expressions and an operand.
- @param expressions: an iterable of expressions
- @type expressions: L{object}
+ @param expressions: expressions to query against
+ @type expressions: iterable of L{object}s
@param operand: an operand
@type operand: a L{NamedConstant}
@return: a deferred iterable of matching L{IDirectoryRecord}s.
Modified: CalendarServer/branches/users/gaya/sharedgroups/twext/who/index.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/who/index.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/who/index.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,3 +1,4 @@
+# -*- test-case-name: twext.who.test.test_xml -*-
##
# Copyright (c) 2006-2013 Apple Inc. All rights reserved.
#
@@ -23,13 +24,14 @@
"DirectoryRecord",
]
+from itertools import chain
+
from twisted.python.constants import Names, NamedConstant
from twisted.internet.defer import succeed, inlineCallbacks, returnValue
-from twext.who.util import MergedConstants, describe, uniqueResult, iterFlags
+from twext.who.util import ConstantsContainer, describe, uniqueResult, iterFlags
from twext.who.idirectory import FieldName as BaseFieldName
-from twext.who.idirectory import MatchType, QueryFlags
-from twext.who.idirectory import DirectoryQueryMatchExpression
+from twext.who.expression import MatchExpression, MatchType, MatchFlags
from twext.who.directory import DirectoryService as BaseDirectoryService
from twext.who.directory import DirectoryRecord as BaseDirectoryRecord
@@ -55,7 +57,7 @@
XML directory service.
"""
- fieldName = MergedConstants(BaseDirectoryService.fieldName, FieldName)
+ fieldName = ConstantsContainer(chain(BaseDirectoryService.fieldName.iterconstants(), FieldName.iterconstants()))
indexedFields = (
BaseFieldName.recordType,
@@ -105,9 +107,9 @@
if flags is not None:
for flag in iterFlags(flags):
- if flag == QueryFlags.NOT:
+ if flag == MatchFlags.NOT:
predicate = lambda x: not x
- elif flag == QueryFlags.caseInsensitive:
+ elif flag == MatchFlags.caseInsensitive:
normalize = lambda x: x.lower()
else:
raise NotImplementedError("Unknown query flag: %s" % (describe(flag),))
@@ -186,11 +188,11 @@
if match(normalize(fieldValue)):
result.add(record)
- return result
+ return succeed(result)
def recordsFromExpression(self, expression, records=None):
- if isinstance(expression, DirectoryQueryMatchExpression):
+ if isinstance(expression, MatchExpression):
if expression.fieldName in self.indexedFields:
return self.indexedRecordsFromMatchExpression(expression, records=records)
else:
Added: CalendarServer/branches/users/gaya/sharedgroups/twext/who/test/test_aggregate.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/who/test/test_aggregate.py (rev 0)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/who/test/test_aggregate.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,239 @@
+##
+# Copyright (c) 2013 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+"""
+Aggregate directory service tests.
+"""
+
+from twisted.python.components import proxyForInterface
+from twisted.trial import unittest
+
+from twext.who.idirectory import IDirectoryService, DirectoryConfigurationError
+from twext.who.aggregate import DirectoryService
+from twext.who.util import ConstantsContainer
+
+from twext.who.test import test_directory, test_xml
+from twext.who.test.test_xml import QueryMixIn, xmlService, TestService as XMLTestService
+
+
+
+class BaseTest(object):
+ def service(self, services=None):
+ if services is None:
+ services = (self.xmlService(),)
+
+ #
+ # Make sure aggregate DirectoryService isn't making
+ # implementation assumptions about the IDirectoryService
+ # objects it gets.
+ #
+ services = tuple((
+ proxyForInterface(IDirectoryService)(s)
+ for s in services
+ ))
+
+ class TestService(DirectoryService, QueryMixIn):
+ pass
+
+ return TestService("xyzzy", services)
+
+
+ def xmlService(self, xmlData=None, serviceClass=None):
+ return xmlService(self.mktemp(), xmlData, serviceClass)
+
+
+
+class DirectoryServiceBaseTest(BaseTest, test_xml.DirectoryServiceBaseTest):
+ def test_repr(self):
+ service = self.service()
+ self.assertEquals(repr(service), "<TestService 'xyzzy'>")
+
+
+
+class DirectoryServiceQueryTest(BaseTest, test_xml.DirectoryServiceQueryTest):
+ pass
+
+
+
+class DirectoryServiceImmutableTest(BaseTest, test_directory.DirectoryServiceImmutableTest):
+ pass
+
+
+
+class AggregatedBaseTest(BaseTest):
+ def service(self):
+ class UsersDirectoryService(XMLTestService):
+ recordType = ConstantsContainer((XMLTestService.recordType.user,))
+
+ class GroupsDirectoryService(XMLTestService):
+ recordType = ConstantsContainer((XMLTestService.recordType.group,))
+
+ usersService = self.xmlService(testXMLConfigUsers, UsersDirectoryService)
+ groupsService = self.xmlService(testXMLConfigGroups, GroupsDirectoryService)
+
+ return BaseTest.service(self, (usersService, groupsService))
+
+
+
+class DirectoryServiceAggregatedBaseTest(AggregatedBaseTest, DirectoryServiceBaseTest):
+ pass
+
+
+
+class DirectoryServiceAggregatedQueryTest(AggregatedBaseTest, test_xml.DirectoryServiceQueryTest):
+ pass
+
+
+
+class DirectoryServiceAggregatedImmutableTest(AggregatedBaseTest, test_directory.DirectoryServiceImmutableTest):
+ pass
+
+
+
+class DirectoryServiceTests(BaseTest, unittest.TestCase):
+ def test_conflictingRecordTypes(self):
+ self.assertRaises(
+ DirectoryConfigurationError,
+ BaseTest.service, self,
+ (self.xmlService(), self.xmlService(testXMLConfigUsers)),
+ )
+
+
+
+testXMLConfigUsers = """<?xml version="1.0" encoding="utf-8"?>
+
+<directory realm="Users Realm">
+
+ <record type="user">
+ <uid>__wsanchez__</uid>
+ <short-name>wsanchez</short-name>
+ <short-name>wilfredo_sanchez</short-name>
+ <full-name>Wilfredo Sanchez</full-name>
+ <password>zehcnasw</password>
+ <email>wsanchez at bitbucket.calendarserver.org</email>
+ <email>wsanchez at devnull.twistedmatrix.com</email>
+ </record>
+
+ <record type="user">
+ <uid>__glyph__</uid>
+ <short-name>glyph</short-name>
+ <full-name>Glyph Lefkowitz</full-name>
+ <password>hpylg</password>
+ <email>glyph at bitbucket.calendarserver.org</email>
+ <email>glyph at devnull.twistedmatrix.com</email>
+ </record>
+
+ <record type="user">
+ <uid>__sagen__</uid>
+ <short-name>sagen</short-name>
+ <full-name>Morgen Sagen</full-name>
+ <password>negas</password>
+ <email>sagen at bitbucket.calendarserver.org</email>
+ <email>shared at example.com</email>
+ </record>
+
+ <record type="user">
+ <uid>__cdaboo__</uid>
+ <short-name>cdaboo</short-name>
+ <full-name>Cyrus Daboo</full-name>
+ <password>suryc</password>
+ <email>cdaboo at bitbucket.calendarserver.org</email>
+ </record>
+
+ <record type="user">
+ <uid>__dre__</uid>
+ <short-name>dre</short-name>
+ <full-name>Andre LaBranche</full-name>
+ <password>erd</password>
+ <email>dre at bitbucket.calendarserver.org</email>
+ <email>shared at example.com</email>
+ </record>
+
+ <record type="user">
+ <uid>__exarkun__</uid>
+ <short-name>exarkun</short-name>
+ <full-name>Jean-Paul Calderone</full-name>
+ <password>nucraxe</password>
+ <email>exarkun at devnull.twistedmatrix.com</email>
+ </record>
+
+ <record type="user">
+ <uid>__dreid__</uid>
+ <short-name>dreid</short-name>
+ <full-name>David Reid</full-name>
+ <password>dierd</password>
+ <email>dreid at devnull.twistedmatrix.com</email>
+ </record>
+
+ <record> <!-- type defaults to "user" -->
+ <uid>__joe__</uid>
+ <short-name>joe</short-name>
+ <full-name>Joe Schmoe</full-name>
+ <password>eoj</password>
+ <email>joe at example.com</email>
+ </record>
+
+ <record> <!-- type defaults to "user" -->
+ <uid>__alyssa__</uid>
+ <short-name>alyssa</short-name>
+ <full-name>Alyssa P. Hacker</full-name>
+ <password>assyla</password>
+ <email>alyssa at example.com</email>
+ </record>
+
+</directory>
+"""
+
+
+testXMLConfigGroups = """<?xml version="1.0" encoding="utf-8"?>
+
+<directory realm="Groups Realm">
+
+ <record type="group">
+ <uid>__calendar-dev__</uid>
+ <short-name>calendar-dev</short-name>
+ <full-name>Calendar Server developers</full-name>
+ <email>dev at bitbucket.calendarserver.org</email>
+ <member-uid>__wsanchez__</member-uid>
+ <member-uid>__glyph__</member-uid>
+ <member-uid>__sagen__</member-uid>
+ <member-uid>__cdaboo__</member-uid>
+ <member-uid>__dre__</member-uid>
+ </record>
+
+ <record type="group">
+ <uid>__twisted__</uid>
+ <short-name>twisted</short-name>
+ <full-name>Twisted Matrix Laboratories</full-name>
+ <email>hack at devnull.twistedmatrix.com</email>
+ <member-uid>__wsanchez__</member-uid>
+ <member-uid>__glyph__</member-uid>
+ <member-uid>__exarkun__</member-uid>
+ <member-uid>__dreid__</member-uid>
+ <member-uid>__dre__</member-uid>
+ </record>
+
+ <record type="group">
+ <uid>__developers__</uid>
+ <short-name>developers</short-name>
+ <full-name>All Developers</full-name>
+ <member-uid>__calendar-dev__</member-uid>
+ <member-uid>__twisted__</member-uid>
+ <member-uid>__alyssa__</member-uid>
+ </record>
+
+</directory>
+"""
Modified: CalendarServer/branches/users/gaya/sharedgroups/twext/who/test/test_directory.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/who/test/test_directory.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/who/test/test_directory.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,7 +15,7 @@
##
"""
-Generic directory service base implementation tests
+Generic directory service base implementation tests.
"""
from zope.interface.verify import verifyObject, BrokenMethodImplementation
@@ -24,7 +24,7 @@
from twisted.trial.unittest import SkipTest
from twisted.internet.defer import inlineCallbacks
-from twext.who.idirectory import QueryNotSupportedError
+from twext.who.idirectory import QueryNotSupportedError, NotAllowedError
from twext.who.idirectory import RecordType, FieldName
from twext.who.idirectory import IDirectoryService, IDirectoryRecord
from twext.who.directory import DirectoryService, DirectoryRecord
@@ -35,7 +35,7 @@
realmName = "xyzzy"
- def _testService(self):
+ def service(self):
if not hasattr(self, "_service"):
self._service = DirectoryService(self.realmName)
return self._service
@@ -44,7 +44,7 @@
class DirectoryServiceTest(BaseTest):
def test_interface(self):
- service = self._testService()
+ service = self.service()
try:
verifyObject(IDirectoryService, service)
except BrokenMethodImplementation as e:
@@ -52,54 +52,92 @@
def test_init(self):
- service = self._testService()
+ service = self.service()
self.assertEquals(service.realmName, self.realmName)
def test_repr(self):
- service = self._testService()
+ service = self.service()
self.assertEquals(repr(service), "<DirectoryService 'xyzzy'>")
- @inlineCallbacks
def test_recordTypes(self):
- service = self._testService()
+ service = self.service()
self.assertEquals(
- set((yield service.recordTypes())),
+ set(service.recordTypes()),
set(service.recordType.iterconstants())
)
@inlineCallbacks
def test_recordsFromQueryNone(self):
- service = self._testService()
+ service = self.service()
records = (yield service.recordsFromQuery(()))
for record in records:
self.failTest("No records expected")
def test_recordsFromQueryBogus(self):
- service = self._testService()
+ service = self.service()
self.assertFailure(service.recordsFromQuery((object(),)), QueryNotSupportedError)
def test_recordWithUID(self):
raise SkipTest("Subclasses should implement this test.")
+
def test_recordWithGUID(self):
raise SkipTest("Subclasses should implement this test.")
+
def test_recordsWithRecordType(self):
raise SkipTest("Subclasses should implement this test.")
+
def test_recordWithShortName(self):
raise SkipTest("Subclasses should implement this test.")
+
def test_recordsWithEmailAddress(self):
raise SkipTest("Subclasses should implement this test.")
+class DirectoryServiceImmutableTest(BaseTest):
+ def test_updateRecordsNotAllowed(self):
+ service = self.service()
+
+ newRecord = DirectoryRecord(
+ service,
+ fields = {
+ service.fieldName.uid: "__plugh__",
+ service.fieldName.recordType: service.recordType.user,
+ service.fieldName.shortNames: ("plugh",),
+ }
+ )
+
+ self.assertFailure(
+ service.updateRecords((newRecord,), create=True),
+ NotAllowedError,
+ )
+
+ self.assertFailure(
+ service.updateRecords((newRecord,), create=False),
+ NotAllowedError,
+ )
+
+
+ def test_removeRecordsNotAllowed(self):
+ service = self.service()
+
+ service.removeRecords(())
+ self.assertFailure(
+ service.removeRecords(("foo",)),
+ NotAllowedError,
+ )
+
+
+
class DirectoryRecordTest(BaseTest):
fields_wsanchez = {
FieldName.uid: "UID:wsanchez",
@@ -130,7 +168,7 @@
if fields is None:
fields = self.fields_wsanchez
if service is None:
- service = self._testService()
+ service = self.service()
return DirectoryRecord(service, fields)
@@ -143,7 +181,7 @@
def test_init(self):
- service = self._testService()
+ service = self.service()
wsanchez = self._testRecord(self.fields_wsanchez, service=service)
self.assertEquals(wsanchez.service, service)
Added: CalendarServer/branches/users/gaya/sharedgroups/twext/who/test/test_expression.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/who/test/test_expression.py (rev 0)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/who/test/test_expression.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,55 @@
+##
+# Copyright (c) 2013 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+"""
+Directory service expression tests.
+"""
+
+from twisted.trial import unittest
+
+from twext.who.idirectory import FieldName
+from twext.who.expression import MatchExpression, MatchType, MatchFlags
+
+
+
+class MatchExpressionTest(unittest.TestCase):
+ def test_repr(self):
+ self.assertEquals(
+ "<MatchExpression: 'full names' equals 'Wilfredo Sanchez'>",
+ repr(MatchExpression(
+ FieldName.fullNames,
+ "Wilfredo Sanchez",
+ )),
+ )
+
+ self.assertEquals(
+ "<MatchExpression: 'full names' contains 'Sanchez'>",
+ repr(MatchExpression(
+ FieldName.fullNames,
+ "Sanchez",
+ matchType=MatchType.contains,
+ )),
+ )
+
+ self.assertEquals(
+ "<MatchExpression: 'full names' starts with 'Wilfredo' (not)>",
+ repr(MatchExpression(
+ FieldName.fullNames,
+ "Wilfredo",
+ matchType=MatchType.startsWith,
+ flags=MatchFlags.NOT,
+ )),
+ )
Added: CalendarServer/branches/users/gaya/sharedgroups/twext/who/test/test_util.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/who/test/test_util.py (rev 0)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/who/test/test_util.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,120 @@
+##
+# Copyright (c) 2013 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+"""
+Directory service utility tests.
+"""
+
+from twisted.trial import unittest
+from twisted.python.constants import Names, NamedConstant
+from twisted.python.constants import Flags, FlagConstant
+
+from twext.who.idirectory import DirectoryServiceError
+from twext.who.util import ConstantsContainer
+from twext.who.util import uniqueResult, describe
+
+
+
+class Tools(Names):
+ hammer = NamedConstant()
+ screwdriver = NamedConstant()
+
+ hammer.description = "nail pounder"
+ screwdriver.description = "screw twister"
+
+
+
+class Instruments(Names):
+ hammer = NamedConstant()
+ chisel = NamedConstant()
+
+
+
+class Switches(Flags):
+ r = FlagConstant()
+ g = FlagConstant()
+ b = FlagConstant()
+
+ r.description = "red"
+ g.description = "green"
+ b.description = "blue"
+
+ black = FlagConstant()
+
+
+
+class ConstantsContainerTest(unittest.TestCase):
+ def test_conflict(self):
+ constants = set((Tools.hammer, Instruments.hammer))
+ self.assertRaises(ValueError, ConstantsContainer, constants)
+
+
+ def test_attrs(self):
+ constants = set((Tools.hammer, Tools.screwdriver, Instruments.chisel))
+ container = ConstantsContainer(constants)
+
+ self.assertEquals(container.hammer, Tools.hammer)
+ self.assertEquals(container.screwdriver, Tools.screwdriver)
+ self.assertEquals(container.chisel, Instruments.chisel)
+ self.assertRaises(AttributeError, lambda: container.plugh)
+
+
+ def test_iterconstants(self):
+ constants = set((Tools.hammer, Tools.screwdriver, Instruments.chisel))
+ container = ConstantsContainer(constants)
+
+ self.assertEquals(
+ set(container.iterconstants()),
+ constants,
+ )
+
+ def test_lookupByName(self):
+ constants = set((Instruments.hammer, Tools.screwdriver, Instruments.chisel))
+ container = ConstantsContainer(constants)
+
+ self.assertEquals(
+ container.lookupByName("hammer"),
+ Instruments.hammer,
+ )
+ self.assertEquals(
+ container.lookupByName("screwdriver"),
+ Tools.screwdriver,
+ )
+ self.assertEquals(
+ container.lookupByName("chisel"),
+ Instruments.chisel,
+ )
+
+ self.assertRaises(
+ ValueError,
+ container.lookupByName, "plugh",
+ )
+
+
+
+class UtilTest(unittest.TestCase):
+ def test_uniqueResult(self):
+ self.assertEquals(1, uniqueResult((1,)))
+ self.assertRaises(DirectoryServiceError, uniqueResult, (1,2,3))
+
+ def test_describe(self):
+ self.assertEquals("nail pounder", describe(Tools.hammer))
+ self.assertEquals("hammer", describe(Instruments.hammer))
+
+ def test_describeFlags(self):
+ self.assertEquals("blue", describe(Switches.b))
+ self.assertEquals("red|green", describe(Switches.r|Switches.g))
+ self.assertEquals("blue|black", describe(Switches.b|Switches.black))
Modified: CalendarServer/branches/users/gaya/sharedgroups/twext/who/test/test_xml.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/who/test/test_xml.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/who/test/test_xml.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -15,17 +15,18 @@
##
"""
-XML directory service tests
+XML directory service tests.
"""
from time import sleep
+from twisted.trial import unittest
from twisted.python.filepath import FilePath
from twisted.internet.defer import inlineCallbacks
from twext.who.idirectory import NoSuchRecordError
-from twext.who.idirectory import DirectoryQueryMatchExpression
-from twext.who.idirectory import Operand, MatchType, QueryFlags
+from twext.who.idirectory import Operand
+from twext.who.expression import MatchExpression, MatchType, MatchFlags
from twext.who.xml import ParseError
from twext.who.xml import DirectoryService, DirectoryRecord
@@ -33,175 +34,119 @@
-xmlRealmName = "Test Realm"
+class BaseTest(unittest.TestCase):
+ def service(self, xmlData=None):
+ return xmlService(self.mktemp(), xmlData)
-testXMLConfig = """<?xml version="1.0" encoding="utf-8"?>
-<directory realm="xyzzy">
+ def assertRecords(self, records, uids):
+ self.assertEquals(
+ frozenset((record.uid for record in records)),
+ frozenset((uids)),
+ )
- <record type="user">
- <uid>__wsanchez__</uid>
- <short-name>wsanchez</short-name>
- <short-name>wilfredo_sanchez</short-name>
- <full-name>Wilfredo Sanchez</full-name>
- <password>zehcnasw</password>
- <email>wsanchez at bitbucket.calendarserver.org</email>
- <email>wsanchez at devnull.twistedmatrix.com</email>
- </record>
- <record type="user">
- <uid>__glyph__</uid>
- <short-name>glyph</short-name>
- <full-name>Glyph Lefkowitz</full-name>
- <password>hpylg</password>
- <email>glyph at bitbucket.calendarserver.org</email>
- <email>glyph at devnull.twistedmatrix.com</email>
- </record>
- <record type="user">
- <uid>__sagen__</uid>
- <short-name>sagen</short-name>
- <full-name>Morgen Sagen</full-name>
- <password>negas</password>
- <email>sagen at bitbucket.calendarserver.org</email>
- <email>shared at example.com</email>
- </record>
+class DirectoryServiceBaseTest(BaseTest, test_directory.DirectoryServiceTest):
+ def test_repr(self):
+ service = self.service()
- <record type="user">
- <uid>__cdaboo__</uid>
- <short-name>cdaboo</short-name>
- <full-name>Cyrus Daboo</full-name>
- <password>suryc</password>
- <email>cdaboo at bitbucket.calendarserver.org</email>
- </record>
+ self.assertEquals(repr(service), "<TestService (not loaded)>")
+ service.loadRecords()
+ self.assertEquals(repr(service), "<TestService 'xyzzy'>")
- <record type="user">
- <uid>__dre__</uid>
- <short-name>dre</short-name>
- <full-name>Andre LaBranche</full-name>
- <password>erd</password>
- <email>dre at bitbucket.calendarserver.org</email>
- <email>shared at example.com</email>
- </record>
- <record type="user">
- <uid>__exarkun__</uid>
- <short-name>exarkun</short-name>
- <full-name>Jean-Paul Calderone</full-name>
- <password>nucraxe</password>
- <email>exarkun at devnull.twistedmatrix.com</email>
- </record>
+ @inlineCallbacks
+ def test_recordWithUID(self):
+ service = self.service()
- <record type="user">
- <uid>__dreid__</uid>
- <short-name>dreid</short-name>
- <full-name>David Reid</full-name>
- <password>dierd</password>
- <email>dreid at devnull.twistedmatrix.com</email>
- </record>
+ record = (yield service.recordWithUID("__null__"))
+ self.assertEquals(record, None)
- <record> <!-- type defaults to "user" -->
- <uid>__joe__</uid>
- <short-name>joe</short-name>
- <full-name>Joe Schmoe</full-name>
- <password>eoj</password>
- <email>joe at example.com</email>
- </record>
+ record = (yield service.recordWithUID("__wsanchez__"))
+ self.assertEquals(record.uid, "__wsanchez__")
- <record>
- <uid>__alyssa__</uid>
- <short-name>alyssa</short-name>
- <full-name>Alyssa P. Hacker</full-name>
- <password>assyla</password>
- <email>alyssa at example.com</email>
- </record>
- <record type="group">
- <uid>__calendar-dev__</uid>
- <short-name>calendar-dev</short-name>
- <full-name>Calendar Server developers</full-name>
- <email>dev at bitbucket.calendarserver.org</email>
- <member-uid>__wsanchez__</member-uid>
- <member-uid>__glyph__</member-uid>
- <member-uid>__sagen__</member-uid>
- <member-uid>__cdaboo__</member-uid>
- <member-uid>__dre__</member-uid>
- </record>
+ @inlineCallbacks
+ def test_recordWithGUID(self):
+ service = self.service()
+ record = (yield service.recordWithGUID("6C495FCD-7E78-4D5C-AA66-BC890AD04C9D"))
+ self.assertEquals(record, None)
- <record type="group">
- <uid>__twisted__</uid>
- <short-name>twisted</short-name>
- <full-name>Twisted Matrix Laboratories</full-name>
- <email>hack at devnull.twistedmatrix.com</email>
- <member-uid>__wsanchez__</member-uid>
- <member-uid>__glyph__</member-uid>
- <member-uid>__exarkun__</member-uid>
- <member-uid>__dreid__</member-uid>
- <member-uid>__dre__</member-uid>
- </record>
+ @inlineCallbacks
+ def test_recordsWithRecordType(self):
+ service = self.service()
- <record type="group">
- <uid>__developers__</uid>
- <short-name>developers</short-name>
- <full-name>All Developers</full-name>
- <member-uid>__calendar-dev__</member-uid>
- <member-uid>__twisted__</member-uid>
- <member-uid>__alyssa__</member-uid>
- </record>
+ records = (yield service.recordsWithRecordType(object()))
+ self.assertEquals(set(records), set())
-</directory>
-"""
+ records = (yield service.recordsWithRecordType(service.recordType.user))
+ self.assertRecords(records,
+ (
+ "__wsanchez__",
+ "__glyph__",
+ "__sagen__",
+ "__cdaboo__",
+ "__dre__",
+ "__exarkun__",
+ "__dreid__",
+ "__alyssa__",
+ "__joe__",
+ ),
+ )
+ records = (yield service.recordsWithRecordType(service.recordType.group))
+ self.assertRecords(records,
+ (
+ "__calendar-dev__",
+ "__twisted__",
+ "__developers__",
+ ),
+ )
-class BaseTest(object):
- def _testService(self, xmlData=None):
- if xmlData is None:
- xmlData = testXMLConfig
+ @inlineCallbacks
+ def test_recordWithShortName(self):
+ service = self.service()
- filePath = FilePath(self.mktemp())
- filePath.setContent(xmlData)
+ record = (yield service.recordWithShortName(service.recordType.user, "null"))
+ self.assertEquals(record, None)
- class TestService(DirectoryService):
- def query(self, field, value, matchType=MatchType.equals, flags=None):
- name = getattr(self.fieldName, field)
- assert name is not None
- return DirectoryQueryMatchExpression(
- name, value,
- matchType = matchType,
- flags = flags,
- )
+ record = (yield service.recordWithShortName(service.recordType.user, "wsanchez"))
+ self.assertEquals(record.uid, "__wsanchez__")
- return TestService(filePath)
+ record = (yield service.recordWithShortName(service.recordType.user, "wilfredo_sanchez"))
+ self.assertEquals(record.uid, "__wsanchez__")
+ @inlineCallbacks
+ def test_recordsWithEmailAddress(self):
+ service = self.service()
-class DirectoryServiceTest(BaseTest, test_directory.DirectoryServiceTest):
- def test_repr(self):
- service = self._testService()
+ records = (yield service.recordsWithEmailAddress("wsanchez at bitbucket.calendarserver.org"))
+ self.assertRecords(records, ("__wsanchez__",))
- self.assertEquals(repr(service), "<TestService (not loaded)>")
- service.loadRecords()
- self.assertEquals(repr(service), "<TestService 'xyzzy'>")
+ records = (yield service.recordsWithEmailAddress("wsanchez at devnull.twistedmatrix.com"))
+ self.assertRecords(records, ("__wsanchez__",))
+ records = (yield service.recordsWithEmailAddress("shared at example.com"))
+ self.assertRecords(records, ("__sagen__", "__dre__"))
- def assertRecords(self, records, uids):
- self.assertEquals(
- frozenset((record.uid for record in records)),
- frozenset((uids)),
- )
+class DirectoryServiceRealmTest(BaseTest):
def test_realmNameImmutable(self):
def setRealmName():
- service = self._testService()
+ service = self.service()
service.realmName = "foo"
self.assertRaises(AssertionError, setRealmName)
+
+class DirectoryServiceParsingTest(BaseTest):
def test_reloadInterval(self):
- service = self._testService()
+ service = self.service()
service.loadRecords(stat=False)
lastRefresh = service._lastRefresh
@@ -213,7 +158,7 @@
def test_reloadStat(self):
- service = self._testService()
+ service = self.service()
service.loadRecords(loadNow=True)
lastRefresh = service._lastRefresh
@@ -225,13 +170,13 @@
def test_badXML(self):
- service = self._testService(xmlData="Hello")
+ service = self.service(xmlData="Hello")
self.assertRaises(ParseError, service.loadRecords)
def test_badRootElement(self):
- service = self._testService(xmlData=
+ service = self.service(xmlData=
"""<?xml version="1.0" encoding="utf-8"?>
<frobnitz />
@@ -248,7 +193,7 @@
def test_noRealmName(self):
- service = self._testService(xmlData=
+ service = self.service(xmlData=
"""<?xml version="1.0" encoding="utf-8"?>
<directory />
@@ -264,86 +209,53 @@
raise AssertionError
- @inlineCallbacks
- def test_recordWithUID(self):
- service = self._testService()
+ def test_unknownFieldElementsClean(self):
+ service = self.service()
+ self.assertEquals(set(service.unknownFieldElements), set())
- record = (yield service.recordWithUID("__null__"))
- self.assertEquals(record, None)
- record = (yield service.recordWithUID("__wsanchez__"))
- self.assertEquals(record.uid, "__wsanchez__")
+ def test_unknownFieldElementsDirty(self):
+ service = self.service(xmlData=
+"""<?xml version="1.0" encoding="utf-8"?>
+<directory realm="Unknown Record Types">
+ <record type="user">
+ <uid>__wsanchez__</uid>
+ <short-name>wsanchez</short-name>
+ <political-affiliation>Community and Freedom Party</political-affiliation>
+ </record>
+</directory>
+"""
+ )
+ self.assertEquals(set(service.unknownFieldElements), set(("political-affiliation",)))
- @inlineCallbacks
- def test_recordWithGUID(self):
- service = self._testService()
- record = (yield service.recordWithGUID("6C495FCD-7E78-4D5C-AA66-BC890AD04C9D"))
- self.assertEquals(record, None)
- @inlineCallbacks
- def test_recordsWithRecordType(self):
- service = self._testService()
+ def test_unknownRecordTypesClean(self):
+ service = self.service()
+ self.assertEquals(set(service.unknownRecordTypes), set())
- records = (yield service.recordsWithRecordType(object()))
- self.assertEquals(set(records), set())
- records = (yield service.recordsWithRecordType(service.recordType.user))
- self.assertRecords(records,
- (
- "__wsanchez__",
- "__glyph__",
- "__sagen__",
- "__cdaboo__",
- "__dre__",
- "__exarkun__",
- "__dreid__",
- "__alyssa__",
- "__joe__",
- ),
- )
+ def test_unknownRecordTypesDirty(self):
+ service = self.service(xmlData=
+"""<?xml version="1.0" encoding="utf-8"?>
- records = (yield service.recordsWithRecordType(service.recordType.group))
- self.assertRecords(records,
- (
- "__calendar-dev__",
- "__twisted__",
- "__developers__",
- ),
+<directory realm="Unknown Record Types">
+ <record type="camera">
+ <uid>__d600__</uid>
+ <short-name>d600</short-name>
+ <full-name>Nikon D600</full-name>
+ </record>
+</directory>
+"""
)
+ self.assertEquals(set(service.unknownRecordTypes), set(("camera",)))
- @inlineCallbacks
- def test_recordWithShortName(self):
- service = self._testService()
- record = (yield service.recordWithShortName(service.recordType.user, "null"))
- self.assertEquals(record, None)
-
- record = (yield service.recordWithShortName(service.recordType.user, "wsanchez"))
- self.assertEquals(record.uid, "__wsanchez__")
-
- record = (yield service.recordWithShortName(service.recordType.user, "wilfredo_sanchez"))
- self.assertEquals(record.uid, "__wsanchez__")
-
-
+class DirectoryServiceQueryTest(BaseTest):
@inlineCallbacks
- def test_recordsWithEmailAddress(self):
- service = self._testService()
-
- records = (yield service.recordsWithEmailAddress("wsanchez at bitbucket.calendarserver.org"))
- self.assertRecords(records, ("__wsanchez__",))
-
- records = (yield service.recordsWithEmailAddress("wsanchez at devnull.twistedmatrix.com"))
- self.assertRecords(records, ("__wsanchez__",))
-
- records = (yield service.recordsWithEmailAddress("shared at example.com"))
- self.assertRecords(records, ("__sagen__", "__dre__"))
-
-
- @inlineCallbacks
def test_queryAnd(self):
- service = self._testService()
+ service = self.service()
records = yield service.recordsFromQuery(
(
service.query("emailAddresses", "shared at example.com"),
@@ -355,8 +267,24 @@
@inlineCallbacks
+ def test_queryAndNoneFirst(self):
+ """
+ Test optimized case, where first expression yields no results.
+ """
+ service = self.service()
+ records = yield service.recordsFromQuery(
+ (
+ service.query("emailAddresses", "nobody at example.com"),
+ service.query("shortNames", "sagen"),
+ ),
+ operand=Operand.AND
+ )
+ self.assertRecords(records, ())
+
+
+ @inlineCallbacks
def test_queryOr(self):
- service = self._testService()
+ service = self.service()
records = yield service.recordsFromQuery(
(
service.query("emailAddresses", "shared at example.com"),
@@ -369,11 +297,11 @@
@inlineCallbacks
def test_queryNot(self):
- service = self._testService()
+ service = self.service()
records = yield service.recordsFromQuery(
(
service.query("emailAddresses", "shared at example.com"),
- service.query("shortNames", "sagen", flags=QueryFlags.NOT),
+ service.query("shortNames", "sagen", flags=MatchFlags.NOT),
),
operand=Operand.AND
)
@@ -382,11 +310,11 @@
@inlineCallbacks
def test_queryNotNoIndex(self):
- service = self._testService()
+ service = self.service()
records = yield service.recordsFromQuery(
(
service.query("emailAddresses", "shared at example.com"),
- service.query("fullNames", "Andre LaBranche", flags=QueryFlags.NOT),
+ service.query("fullNames", "Andre LaBranche", flags=MatchFlags.NOT),
),
operand=Operand.AND
)
@@ -395,25 +323,25 @@
@inlineCallbacks
def test_queryCaseInsensitive(self):
- service = self._testService()
+ service = self.service()
records = yield service.recordsFromQuery((
- service.query("shortNames", "SagEn", flags=QueryFlags.caseInsensitive),
+ service.query("shortNames", "SagEn", flags=MatchFlags.caseInsensitive),
))
self.assertRecords(records, ("__sagen__",))
@inlineCallbacks
def test_queryCaseInsensitiveNoIndex(self):
- service = self._testService()
+ service = self.service()
records = yield service.recordsFromQuery((
- service.query("fullNames", "moRGen SAGen", flags=QueryFlags.caseInsensitive),
+ service.query("fullNames", "moRGen SAGen", flags=MatchFlags.caseInsensitive),
))
self.assertRecords(records, ("__sagen__",))
@inlineCallbacks
def test_queryStartsWith(self):
- service = self._testService()
+ service = self.service()
records = yield service.recordsFromQuery((
service.query("shortNames", "wil", matchType=MatchType.startsWith),
))
@@ -422,7 +350,7 @@
@inlineCallbacks
def test_queryStartsWithNoIndex(self):
- service = self._testService()
+ service = self.service()
records = yield service.recordsFromQuery((
service.query("fullNames", "Wilfredo", matchType=MatchType.startsWith),
))
@@ -431,12 +359,12 @@
@inlineCallbacks
def test_queryStartsWithNot(self):
- service = self._testService()
+ service = self.service()
records = yield service.recordsFromQuery((
service.query(
"shortNames", "w",
matchType = MatchType.startsWith,
- flags = QueryFlags.NOT,
+ flags = MatchFlags.NOT,
),
))
self.assertRecords(
@@ -465,12 +393,12 @@
included or not? It is, because one matches the query, but
should NOT require that all match?
"""
- service = self._testService()
+ service = self.service()
records = yield service.recordsFromQuery((
service.query(
"shortNames", "wil",
matchType = MatchType.startsWith,
- flags = QueryFlags.NOT,
+ flags = MatchFlags.NOT,
),
))
self.assertRecords(
@@ -494,12 +422,12 @@
@inlineCallbacks
def test_queryStartsWithNotNoIndex(self):
- service = self._testService()
+ service = self.service()
records = yield service.recordsFromQuery((
service.query(
"fullNames", "Wilfredo",
matchType = MatchType.startsWith,
- flags = QueryFlags.NOT,
+ flags = MatchFlags.NOT,
),
))
self.assertRecords(
@@ -522,12 +450,12 @@
@inlineCallbacks
def test_queryStartsWithCaseInsensitive(self):
- service = self._testService()
+ service = self.service()
records = yield service.recordsFromQuery((
service.query(
"shortNames", "WIL",
matchType = MatchType.startsWith,
- flags = QueryFlags.caseInsensitive,
+ flags = MatchFlags.caseInsensitive,
),
))
self.assertRecords(records, ("__wsanchez__",))
@@ -535,12 +463,12 @@
@inlineCallbacks
def test_queryStartsWithCaseInsensitiveNoIndex(self):
- service = self._testService()
+ service = self.service()
records = yield service.recordsFromQuery((
service.query(
"fullNames", "wilfrEdo",
matchType = MatchType.startsWith,
- flags = QueryFlags.caseInsensitive,
+ flags = MatchFlags.caseInsensitive,
),
))
self.assertRecords(records, ("__wsanchez__",))
@@ -548,7 +476,7 @@
@inlineCallbacks
def test_queryContains(self):
- service = self._testService()
+ service = self.service()
records = yield service.recordsFromQuery((
service.query("shortNames", "sanchez", matchType=MatchType.contains),
))
@@ -557,7 +485,7 @@
@inlineCallbacks
def test_queryContainsNoIndex(self):
- service = self._testService()
+ service = self.service()
records = yield service.recordsFromQuery((
service.query("fullNames", "fred", matchType=MatchType.contains),
))
@@ -566,12 +494,12 @@
@inlineCallbacks
def test_queryContainsNot(self):
- service = self._testService()
+ service = self.service()
records = yield service.recordsFromQuery((
service.query(
"shortNames", "sanchez",
matchType = MatchType.contains,
- flags = QueryFlags.NOT,
+ flags = MatchFlags.NOT,
),
))
self.assertRecords(
@@ -594,12 +522,12 @@
@inlineCallbacks
def test_queryContainsNotNoIndex(self):
- service = self._testService()
+ service = self.service()
records = yield service.recordsFromQuery((
service.query(
"fullNames", "fred",
matchType = MatchType.contains,
- flags = QueryFlags.NOT,
+ flags = MatchFlags.NOT,
),
))
self.assertRecords(
@@ -622,12 +550,12 @@
@inlineCallbacks
def test_queryContainsCaseInsensitive(self):
- service = self._testService()
+ service = self.service()
records = yield service.recordsFromQuery((
service.query(
"shortNames", "Sanchez",
matchType=MatchType.contains,
- flags=QueryFlags.caseInsensitive,
+ flags=MatchFlags.caseInsensitive,
),
))
self.assertRecords(records, ("__wsanchez__",))
@@ -635,62 +563,22 @@
@inlineCallbacks
def test_queryContainsCaseInsensitiveNoIndex(self):
- service = self._testService()
+ service = self.service()
records = yield service.recordsFromQuery((
service.query(
"fullNames", "frEdo",
matchType=MatchType.contains,
- flags=QueryFlags.caseInsensitive,
+ flags=MatchFlags.caseInsensitive,
),
))
self.assertRecords(records, ("__wsanchez__",))
- def test_unknownRecordTypesClean(self):
- service = self._testService()
- self.assertEquals(set(service.unknownRecordTypes), set())
-
- def test_unknownRecordTypesDirty(self):
- service = self._testService(xmlData=
-"""<?xml version="1.0" encoding="utf-8"?>
-
-<directory realm="Unknown Record Types">
- <record type="camera">
- <uid>__d600__</uid>
- <short-name>d600</short-name>
- <full-name>Nikon D600</full-name>
- </record>
-</directory>
-"""
- )
- self.assertEquals(set(service.unknownRecordTypes), set(("camera",)))
-
-
- def test_unknownFieldElementsClean(self):
- service = self._testService()
- self.assertEquals(set(service.unknownFieldElements), set())
-
-
- def test_unknownFieldElementsDirty(self):
- service = self._testService(xmlData=
-"""<?xml version="1.0" encoding="utf-8"?>
-
-<directory realm="Unknown Record Types">
- <record type="user">
- <uid>__wsanchez__</uid>
- <short-name>wsanchez</short-name>
- <political-affiliation>Community and Freedom Party</political-affiliation>
- </record>
-</directory>
-"""
- )
- self.assertEquals(set(service.unknownFieldElements), set(("political-affiliation",)))
-
-
+class DirectoryServiceMutableTest(BaseTest):
@inlineCallbacks
def test_updateRecord(self):
- service = self._testService()
+ service = self.service()
record = (yield service.recordWithUID("__wsanchez__"))
@@ -712,7 +600,7 @@
@inlineCallbacks
def test_addRecord(self):
- service = self._testService()
+ service = self.service()
newRecord = DirectoryRecord(
service,
@@ -736,7 +624,7 @@
def test_addRecordNoCreate(self):
- service = self._testService()
+ service = self.service()
newRecord = DirectoryRecord(
service,
@@ -752,7 +640,7 @@
@inlineCallbacks
def test_removeRecord(self):
- service = self._testService()
+ service = self.service()
yield service.removeRecords(("__wsanchez__",))
@@ -765,7 +653,7 @@
def test_removeRecordNoExist(self):
- service = self._testService()
+ service = self.service()
return service.removeRecords(("__plugh__",))
@@ -774,7 +662,7 @@
class DirectoryRecordTest(BaseTest, test_directory.DirectoryRecordTest):
@inlineCallbacks
def test_members(self):
- service = self._testService()
+ service = self.service()
record = (yield service.recordWithUID("__wsanchez__"))
members = (yield record.members())
@@ -806,7 +694,7 @@
@inlineCallbacks
def test_groups(self):
- service = self._testService()
+ service = self.service()
record = (yield service.recordWithUID("__wsanchez__"))
groups = (yield record.groups())
@@ -817,3 +705,153 @@
"__twisted__",
))
)
+
+
+
+class QueryMixIn(object):
+ def query(self, field, value, matchType=MatchType.equals, flags=None):
+ name = getattr(self.fieldName, field)
+ assert name is not None
+ return MatchExpression(
+ name, value,
+ matchType = matchType,
+ flags = flags,
+ )
+
+
+
+class TestService(DirectoryService, QueryMixIn):
+ pass
+
+
+
+def xmlService(tmp, xmlData=None, serviceClass=None):
+ if xmlData is None:
+ xmlData = testXMLConfig
+
+ if serviceClass is None:
+ serviceClass = TestService
+
+ filePath = FilePath(tmp)
+ filePath.setContent(xmlData)
+
+ return serviceClass(filePath)
+
+
+
+testXMLConfig = """<?xml version="1.0" encoding="utf-8"?>
+
+<directory realm="xyzzy">
+
+ <record type="user">
+ <uid>__wsanchez__</uid>
+ <short-name>wsanchez</short-name>
+ <short-name>wilfredo_sanchez</short-name>
+ <full-name>Wilfredo Sanchez</full-name>
+ <password>zehcnasw</password>
+ <email>wsanchez at bitbucket.calendarserver.org</email>
+ <email>wsanchez at devnull.twistedmatrix.com</email>
+ </record>
+
+ <record type="user">
+ <uid>__glyph__</uid>
+ <short-name>glyph</short-name>
+ <full-name>Glyph Lefkowitz</full-name>
+ <password>hpylg</password>
+ <email>glyph at bitbucket.calendarserver.org</email>
+ <email>glyph at devnull.twistedmatrix.com</email>
+ </record>
+
+ <record type="user">
+ <uid>__sagen__</uid>
+ <short-name>sagen</short-name>
+ <full-name>Morgen Sagen</full-name>
+ <password>negas</password>
+ <email>sagen at bitbucket.calendarserver.org</email>
+ <email>shared at example.com</email>
+ </record>
+
+ <record type="user">
+ <uid>__cdaboo__</uid>
+ <short-name>cdaboo</short-name>
+ <full-name>Cyrus Daboo</full-name>
+ <password>suryc</password>
+ <email>cdaboo at bitbucket.calendarserver.org</email>
+ </record>
+
+ <record type="user">
+ <uid>__dre__</uid>
+ <short-name>dre</short-name>
+ <full-name>Andre LaBranche</full-name>
+ <password>erd</password>
+ <email>dre at bitbucket.calendarserver.org</email>
+ <email>shared at example.com</email>
+ </record>
+
+ <record type="user">
+ <uid>__exarkun__</uid>
+ <short-name>exarkun</short-name>
+ <full-name>Jean-Paul Calderone</full-name>
+ <password>nucraxe</password>
+ <email>exarkun at devnull.twistedmatrix.com</email>
+ </record>
+
+ <record type="user">
+ <uid>__dreid__</uid>
+ <short-name>dreid</short-name>
+ <full-name>David Reid</full-name>
+ <password>dierd</password>
+ <email>dreid at devnull.twistedmatrix.com</email>
+ </record>
+
+ <record> <!-- type defaults to "user" -->
+ <uid>__joe__</uid>
+ <short-name>joe</short-name>
+ <full-name>Joe Schmoe</full-name>
+ <password>eoj</password>
+ <email>joe at example.com</email>
+ </record>
+
+ <record> <!-- type defaults to "user" -->
+ <uid>__alyssa__</uid>
+ <short-name>alyssa</short-name>
+ <full-name>Alyssa P. Hacker</full-name>
+ <password>assyla</password>
+ <email>alyssa at example.com</email>
+ </record>
+
+ <record type="group">
+ <uid>__calendar-dev__</uid>
+ <short-name>calendar-dev</short-name>
+ <full-name>Calendar Server developers</full-name>
+ <email>dev at bitbucket.calendarserver.org</email>
+ <member-uid>__wsanchez__</member-uid>
+ <member-uid>__glyph__</member-uid>
+ <member-uid>__sagen__</member-uid>
+ <member-uid>__cdaboo__</member-uid>
+ <member-uid>__dre__</member-uid>
+ </record>
+
+ <record type="group">
+ <uid>__twisted__</uid>
+ <short-name>twisted</short-name>
+ <full-name>Twisted Matrix Laboratories</full-name>
+ <email>hack at devnull.twistedmatrix.com</email>
+ <member-uid>__wsanchez__</member-uid>
+ <member-uid>__glyph__</member-uid>
+ <member-uid>__exarkun__</member-uid>
+ <member-uid>__dreid__</member-uid>
+ <member-uid>__dre__</member-uid>
+ </record>
+
+ <record type="group">
+ <uid>__developers__</uid>
+ <short-name>developers</short-name>
+ <full-name>All Developers</full-name>
+ <member-uid>__calendar-dev__</member-uid>
+ <member-uid>__twisted__</member-uid>
+ <member-uid>__alyssa__</member-uid>
+ </record>
+
+</directory>
+"""
Modified: CalendarServer/branches/users/gaya/sharedgroups/twext/who/util.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/who/util.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/who/util.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,3 +1,4 @@
+# -*- test-case-name: twext.who.test.test_util -*-
##
# Copyright (c) 2013 Apple Inc. All rights reserved.
#
@@ -19,71 +20,47 @@
"""
__all__ = [
- "MergedConstants",
+ "ConstantsContainer",
"uniqueResult",
"describe",
"iterFlags",
]
-from types import FunctionType
+from twisted.python.constants import FlagConstant
-from twisted.python.constants import NamedConstant
-
from twext.who.idirectory import DirectoryServiceError
-class MergedConstants(object):
+class ConstantsContainer(object):
"""
- Work-around for the fact that Names is apparently not subclassable
- and doesn't provide a way to merge multiple Names classes.
+ A container for constants.
"""
- def __init__(self, *containers):
- seenNames = set()
- myContainers = set()
- for container in containers:
- for constant in container.iterconstants():
- if constant.name in seenNames:
- raise ValueError(
- "Multiple constants with the same name may not be merged: %s"
- % (constant.name,)
- )
- seenNames.add(constant.name)
+ def __init__(self, constants):
+ myConstants = {}
+ for constant in constants:
+ if constant.name in myConstants:
+ raise ValueError("Name conflict: %r" % (constant.name,))
+ myConstants[constant.name] = constant
- if isinstance(container, MergedConstants):
- # Avoid nesting
- myContainers |= container._containers
- else:
- myContainers.add(container)
+ self._constants = myConstants
- self._containers = myContainers
-
def __getattr__(self, name):
- for container in self._containers:
- attr = getattr(container, name, None)
- if attr is not None:
- # Named constant or static method
- if isinstance(attr, (NamedConstant, FunctionType)):
- return attr
+ try:
+ return self._constants[name]
+ except KeyError:
+ raise AttributeError(name)
- raise AttributeError(name)
-
def iterconstants(self):
- for container in self._containers:
- for constant in container.iterconstants():
- yield constant
+ return self._constants.itervalues()
def lookupByName(self, name):
- for container in self._containers:
- try:
- return container.lookupByName(name)
- except ValueError:
- pass
+ try:
+ return self._constants[name]
+ except KeyError:
+ raise ValueError(name)
- raise ValueError(name)
-
-
def uniqueResult(values):
result = None
for value in values:
@@ -95,7 +72,13 @@
def describe(constant):
- return getattr(constant, "description", str(constant))
+ if isinstance(constant, FlagConstant):
+ parts = []
+ for flag in iterFlags(constant):
+ parts.append(getattr(flag, "description", flag.name))
+ return "|".join(parts)
+ else:
+ return getattr(constant, "description", constant.name)
def iterFlags(flags):
Modified: CalendarServer/branches/users/gaya/sharedgroups/twext/who/xml.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twext/who/xml.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twext/who/xml.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,3 +1,4 @@
+# -*- test-case-name: twext.who.test.test_xml -*-
##
# Copyright (c) 2006-2013 Apple Inc. All rights reserved.
#
@@ -127,12 +128,13 @@
attribute = Attribute
value = Value
+ refreshInterval = 4
- def __init__(self, filePath, refreshInterval=4):
+
+ def __init__(self, filePath):
BaseDirectoryService.__init__(self, realmName=noRealmName)
self.filePath = filePath
- self.refreshInterval = refreshInterval
def __repr__(self):
@@ -255,7 +257,7 @@
values = record.fields.get(fieldName, None)
if values is not None:
- if not self.fieldName.isMultiValue(fieldName):
+ if not BaseFieldName.isMultiValue(fieldName):
values = (values,)
for value in values:
@@ -302,7 +304,7 @@
value = fieldNode.text.encode("utf-8")
- if self.fieldName.isMultiValue(fieldName):
+ if BaseFieldName.isMultiValue(fieldName):
values = fields.setdefault(fieldName, [])
values.append(value)
else:
@@ -363,7 +365,7 @@
if name in fieldNames:
tag = fieldNames[name]
- if self.fieldName.isMultiValue(name):
+ if BaseFieldName.isMultiValue(name):
values = value
else:
values = (value,)
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/backup.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/backup.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/backup.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
"""
Utility code for backup and restore
@@ -42,12 +43,12 @@
def debug(string):
if VERBOSE:
- print "DEBUG:", string
+ print("DEBUG:", string)
def funclog(string):
if FUNCLOG:
- print "FUNCLOG:", string
+ print("FUNCLOG:", string)
def logFuncCall(func):
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/datafilters/hiddeninstance.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/datafilters/hiddeninstance.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/datafilters/hiddeninstance.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -33,13 +33,11 @@
@param ical: iCalendar object
@type ical: L{Component} or C{str}
-
+
@return: L{Component} for the filtered calendar data
"""
-
+
master = ical.masterComponent()
- if master is None:
- return ical
for component in tuple(ical.subcomponents()):
if component.name() in ignoredComponents:
continue
@@ -49,15 +47,17 @@
if component.hasProperty(Component.HIDDEN_INSTANCE_PROPERTY):
rid = component.getRecurrenceIDUTC()
ical.removeComponent(component)
-
+
# Add EXDATE and try to preserve same timezone as DTSTART
- dtstart = master.getProperty("DTSTART")
- if dtstart is not None and not dtstart.value().isDateOnly() and dtstart.value().local():
- rid.adjustTimezone(dtstart.value().getTimezone())
- master.addProperty(Property("EXDATE", [rid,]))
-
+ if master is not None:
+ dtstart = master.getProperty("DTSTART")
+ if dtstart is not None and not dtstart.value().isDateOnly() and dtstart.value().local():
+ rid.adjustTimezone(dtstart.value().getTimezone())
+ master.addProperty(Property("EXDATE", [rid, ]))
+
return ical
-
+
+
def merge(self, icalnew, icalold):
"""
Private event merging does not happen
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/datafilters/test/test_hiddeninstances.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/datafilters/test/test_hiddeninstances.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/datafilters/test/test_hiddeninstances.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -21,7 +21,7 @@
class HiddenInstanceFilterTest (twistedcaldav.test.util.TestCase):
def test_public_default(self):
-
+
data = (
(
"Nothing hidden, no recurrence",
@@ -378,7 +378,7 @@
""",
),
(
- "No master, one hidden - not really",
+ "No master, one hidden",
"""BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
@@ -415,21 +415,11 @@
ATTENDEE:mailto:user2 at example.com
ORGANIZER;CN=User 01:mailto:user1 at example.com
END:VEVENT
-BEGIN:VEVENT
-UID:12345-67890
-RECURRENCE-ID:20080603T120000Z
-DTSTART:20080603T123000Z
-DTEND:20080601T133000Z
-ATTENDEE:mailto:user1 at example.com
-ATTENDEE:mailto:user2 at example.com
-ORGANIZER;CN=User 01:mailto:user1 at example.com
-X-CALENDARSERVER-HIDDEN-INSTANCE:T
-END:VEVENT
END:VCALENDAR
""",
),
)
-
+
for title, test, result in data:
ics = Component.fromString(test.replace("\n", "\r\n"))
self.assertEqual(str(HiddenInstanceFilter().filter(ics)), result.replace("\n", "\r\n"), msg="Failed: %s" % (title,))
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/directory/test/test_guidchange.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/directory/test/test_guidchange.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/directory/test/test_guidchange.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
+
from twistedcaldav.directory.directory import DirectoryService
from txdav.xml import element as davxml
@@ -93,14 +95,14 @@
if allowed:
def onError(f):
f.trap(AccessDeniedError)
- #print resource.readDeadProperty(davxml.ACL).toxml()
+ #print(resource.readDeadProperty(davxml.ACL).toxml())
self.fail("%s should have %s privilege on %r" % (principal, privilege.sname(), resource))
d.addErrback(onError)
else:
def onError(f):
f.trap(AccessDeniedError)
def onSuccess(_):
- #print resource.readDeadProperty(davxml.ACL).toxml()
+ #print(resource.readDeadProperty(davxml.ACL).toxml())
self.fail("%s should not have %s privilege on %r" % (principal, privilege.sname(), resource))
d.addCallback(onSuccess)
d.addErrback(onError)
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/directory/test/test_ldapdirectory.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/directory/test/test_ldapdirectory.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/directory/test/test_ldapdirectory.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
try:
from twistedcaldav.directory.ldapdirectory import (
@@ -29,7 +30,7 @@
from string import maketrans
import ldap
except ImportError:
- print "Skipping because ldap module not installed"
+ print("Skipping because ldap module not installed")
else:
from twistedcaldav.test.util import TestCase
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/directory/test/test_livedirectory.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/directory/test/test_livedirectory.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/directory/test/test_livedirectory.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
runLDAPTests = False
runODTests = False
@@ -33,7 +34,7 @@
pass # Don't run live tests
except ImportError:
- print "Could not import ldap module (skipping LDAP tests)"
+ print("Could not import ldap module (skipping LDAP tests)")
try:
from calendarserver.platform.darwin.od import opendirectory, dsattributes
@@ -54,10 +55,10 @@
if "odtestamanda" in recordNames:
runODTests = True
else:
- print "Test OD records not found (skipping OD tests)"
+ print("Test OD records not found (skipping OD tests)")
except ImportError:
- print "Could not import OpenDirectory framework (skipping OD tests)"
+ print("Could not import OpenDirectory framework (skipping OD tests)")
if runLDAPTests or runODTests:
@@ -144,7 +145,7 @@
if runLDAPTests:
from twistedcaldav.directory.ldapdirectory import LdapDirectoryService
- print "Running live LDAP tests against %s" % (testServer,)
+ print("Running live LDAP tests against %s" % (testServer,))
class LiveLDAPDirectoryServiceCase(LiveDirectoryTests, TestCase):
@@ -181,7 +182,7 @@
if runODTests:
from twistedcaldav.directory.appleopendirectory import OpenDirectoryService
- print "Running live OD tests"
+ print("Running live OD tests")
class LiveODDirectoryServiceCase(LiveDirectoryTests, TestCase):
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/directory/test/test_principal.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/directory/test/test_principal.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/directory/test/test_principal.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
import os
@@ -94,7 +95,7 @@
DirectoryPrincipalResource.principalURL(),
"""
for directory in self.directoryServices:
- #print "\n -> %s" % (directory.__class__.__name__,)
+ #print("\n -> %s" % (directory.__class__.__name__,))
provisioningResource = self.principalRootResources[directory.__class__.__name__]
provisioningURL = "/" + directory.__class__.__name__ + "/"
@@ -107,7 +108,7 @@
self.assertEquals(recordTypes, set(directory.recordTypes()))
for recordType in recordTypes:
- #print " -> %s" % (recordType,)
+ #print(" -> %s" % (recordType,))
typeResource = provisioningResource.getChild(recordType)
self.failUnless(isinstance(typeResource, DirectoryPrincipalTypeProvisioningResource))
@@ -126,7 +127,7 @@
self.assertEquals(shortNames, set(expected))
for shortName in shortNames:
- #print " -> %s" % (shortName,)
+ #print(" -> %s" % (shortName,))
recordResource = typeResource.getChild(shortName)
self.failUnless(isinstance(recordResource, DirectoryPrincipalResource))
@@ -627,14 +628,14 @@
Default access controls for principal provisioning resources.
"""
for directory in self.directoryServices:
- #print "\n -> %s" % (directory.__class__.__name__,)
+ #print("\n -> %s" % (directory.__class__.__name__,))
provisioningResource = self.principalRootResources[directory.__class__.__name__]
for args in _authReadOnlyPrivileges(self, provisioningResource, provisioningResource.principalCollectionURL()):
yield self._checkPrivileges(*args)
for recordType in (yield provisioningResource.listChildren()):
- #print " -> %s" % (recordType,)
+ #print(" -> %s" % (recordType,))
typeResource = provisioningResource.getChild(recordType)
for args in _authReadOnlyPrivileges(self, typeResource, typeResource.principalCollectionURL()):
@@ -703,14 +704,14 @@
if allowed:
def onError(f):
f.trap(AccessDeniedError)
- #print resource.readDeadProperty(davxml.ACL)
+ #print(resource.readDeadProperty(davxml.ACL))
self.fail("%s should have %s privilege on %r" % (principal.sname(), privilege.sname(), resource))
d.addErrback(onError)
else:
def expectAccessDenied(f):
f.trap(AccessDeniedError)
def onSuccess(_):
- #print resource.readDeadProperty(davxml.ACL)
+ #print(resource.readDeadProperty(davxml.ACL))
self.fail("%s should not have %s privilege on %r" % (principal.sname(), privilege.sname(), resource))
d.addCallbacks(onSuccess, expectAccessDenied)
return d
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/extensions.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/extensions.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/extensions.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,6 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
"""
Extensions to web2.dav
@@ -502,7 +503,7 @@
else:
mimeType = child.contentType()
if mimeType is None:
- print 'BAD contentType() IMPLEMENTATION', child
+ print('BAD contentType() IMPLEMENTATION', child)
contentType = 'application/octet-stream'
else:
contentType = "%s/%s" % (mimeType.mediaType, mimeType.mediaSubtype)
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/ical.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/ical.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/ical.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1281,7 +1281,7 @@
is added as STATUS:CANCELLED and the EXDATE removed.
@param rid: recurrence-id value
- @type rid: L{PyCalendarDateTime}
+ @type rid: L{PyCalendarDateTime} or C{str}
@param allowCancelled: whether to allow a STATUS:CANCELLED override
@type allowCancelled: C{bool}
@@ -1296,6 +1296,9 @@
if master is None:
return None
+ if isinstance(rid, str):
+ rid = PyCalendarDateTime.parseText(rid) if rid else None
+
# TODO: Check that the recurrence-id is a valid instance
# For now we just check that there is no matching EXDATE
didCancel = False
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/localization.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/localization.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/localization.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,8 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
+from __future__ import with_statement
-from __future__ import with_statement
import gettext
import inspect
import os
@@ -46,8 +47,8 @@
from localization import translationTo
with translationTo('de'):
- print _("Hello")
- print _("The event will last %(days)d days") % { 'days' : 4 }
+ print(_("Hello"))
+ print(_("The event will last %(days)d days") % { 'days' : 4 })
... Hallo
... Die Veranstaltung dauert 4 Tage
@@ -74,12 +75,12 @@
nesting of "with" contexts, as in:
with translationTo('de'):
- print _("Hello") # in German
+ print(_("Hello") # in German)
with translationTo('fr'):
- print _("Hello") # in French
+ print(_("Hello") # in French)
- print _("Hello") # in German
+ print(_("Hello") # in German)
If a translation file cannot be found for the specified language, it will fall
back to 'en'. If 'en' can't be found, gettext will raise IOError.
@@ -88,12 +89,12 @@
helper methods for date formatting:
with translationTo('en') as trans:
- print trans.dtDate(PyCalendarDateTime.getToday())
+ print(trans.dtDate(PyCalendarDateTime.getToday()))
... Thursday, October 23, 2008
with translationTo('fr') as trans:
- print trans.dtDate(PyCalendarDateTime.getToday())
+ print(trans.dtDate(PyCalendarDateTime.getToday()))
... Jeudi, Octobre 23, 2008
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/method/put.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/method/put.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/method/put.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -31,8 +31,7 @@
from twistedcaldav.caldavxml import caldav_namespace
from twistedcaldav.method.put_common import StoreCalendarObjectResource
-from twistedcaldav.resource import isPseudoCalendarCollectionResource, \
- CalDAVResource
+from twistedcaldav.resource import isPseudoCalendarCollectionResource
log = Logger()
@@ -158,13 +157,6 @@
raise HTTPError(StatusResponse(responsecode.BAD_REQUEST, str(e)))
else:
- result = (yield super(CalDAVResource, self).http_PUT(request))
-
- if not hasattr(request, "extendedLogItems"):
- request.extendedLogItems = {}
- clength = request.headers.getHeader("content-length", 0)
- if clength == 0:
- clength = self.contentLength()
- request.extendedLogItems["cl"] = str(clength)
-
- returnValue(result)
+ # No longer support arbitrary PUTs to resource. Instead we are going to require all the
+ # resource classes we care about to explicitly define their own http_PUT.
+ raise HTTPError(StatusResponse(responsecode.FORBIDDEN, "PUTs not allowed here"))
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/query/expression.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/query/expression.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/query/expression.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,10 +13,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
"""
-Query Expression Elements. These are used to build a 'generic' query expression tree that can then
-be used by different query language generators to produce the actual query syntax required (SQL, xpath eyc).
+Query Expression Elements. These are used to build a 'generic' query
+expression tree that can then be used by different query language
+generators to produce the actual query syntax required (SQL, xpath
+eyc).
"""
__version__ = "0.0"
@@ -329,9 +332,9 @@
e3 = containsExpression("summary", "help", True)
e4 = notExpression(e3)
e5 = andExpression([e1, e2, e4])
- print e5
+ print(e5)
e6 = inExpression("type", ("vevent", "vtodo",), False)
- print e6
+ print(e6)
e7 = notinExpression("type", ("vevent", "vtodo",), False)
- print e7
+ print(e7)
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/query/sqlgenerator.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/query/sqlgenerator.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/query/sqlgenerator.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
"""
SQL statement generator from query expressions.
@@ -320,14 +321,14 @@
e2 = expression.timerangeExpression("20060101T120000Z", "20060101T130000Z", "20060101T080000Z", "20060101T090000Z")
e3 = expression.notcontainsExpression("SUMMARY", "help", True)
e5 = expression.andExpression([e1, e2, e3])
- print e5
+ print(e5)
sql = sqlgenerator(e5, 'dummy-cal', 'dummy-user')
- print sql.generate()
+ print(sql.generate())
e6 = expression.inExpression("TYPE", ("VEVENT", "VTODO",), False)
- print e6
+ print(e6)
sql = sqlgenerator(e6, 'dummy-cal', 'dummy-user')
- print sql.generate()
+ print(sql.generate())
e7 = expression.notinExpression("TYPE", ("VEVENT", "VTODO",), False)
- print e7
+ print(e7)
sql = sqlgenerator(e7, 'dummy-cal', 'dummy-user')
- print sql.generate()
+ print(sql.generate())
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/resource.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/resource.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/resource.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -2320,7 +2320,7 @@
elif qname == (customxml.calendarserver_namespace, "push-transports"):
- if config.Notifications.Services.ApplePushNotifier.Enabled:
+ if config.Notifications.Services.APNS.Enabled:
nodeName = (yield self._newStoreHome.nodeName())
if nodeName:
@@ -2355,8 +2355,8 @@
returnValue(None)
elif qname == (customxml.calendarserver_namespace, "pushkey"):
- if (config.Notifications.Services.AMPNotifier.Enabled or
- config.Notifications.Services.ApplePushNotifier.Enabled):
+ if (config.Notifications.Services.AMP.Enabled or
+ config.Notifications.Services.APNS.Enabled):
nodeName = (yield self._newStoreHome.nodeName())
if nodeName:
returnValue(customxml.PubSubXMPPPushKeyProperty(nodeName))
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/icaldiff.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/icaldiff.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/icaldiff.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -339,11 +339,9 @@
changedRids.append(rid.getText() if rid else "")
# When a master component is present we keep the missing override in place but mark it as hidden.
- # When no master is present we remove the override,
- if exdatesnew is not None:
- overridden.replaceProperty(Property(Component.HIDDEN_INSTANCE_PROPERTY, "T"))
- else:
- returnCalendar.removeComponent(overridden)
+ # When no master is present we now do the same so we can track updates to the override correctly.
+ overridden.replaceProperty(Property(Component.HIDDEN_INSTANCE_PROPERTY, "T"))
+
else:
# We used to generate a 403 here - but instead we now ignore this error and let the server data
# override the client
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/imip/outbound.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/imip/outbound.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/imip/outbound.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -23,7 +23,6 @@
from cStringIO import StringIO
import os
-from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import email.utils
@@ -39,7 +38,7 @@
from twisted.web.template import XMLString, TEMPLATE_NAMESPACE, Element, renderer, flattenString, tags
from twistedcaldav.config import config
from twistedcaldav.ical import Component
-from twistedcaldav.localization import translationTo, _
+from twistedcaldav.localization import translationTo, _, getLanguage
from twistedcaldav.scheduling.cuaddress import normalizeCUAddr
from twistedcaldav.scheduling.imip.smtpsender import SMTPSender
from txdav.common.datastore.sql_tables import schema
@@ -81,7 +80,7 @@
smtpSender = SMTPSender(settings.Username, settings.Password,
settings.UseSSL, settings.Server, settings.Port)
cls.mailSender = MailSender(settings.Address,
- settings.SuppressionDays, smtpSender=smtpSender)
+ settings.SuppressionDays, smtpSender, getLanguage(config))
return cls.mailSender
@inlineCallbacks
@@ -302,15 +301,15 @@
Generates outbound IMIP messages and sends them.
"""
- def __init__(self, address, suppressionDays, smtpSender):
+ def __init__(self, address, suppressionDays, smtpSender, language):
self.address = address
self.suppressionDays = suppressionDays
self.smtpSender = smtpSender
+ self.language = language
@inlineCallbacks
- def outbound(self, txn, originator, recipient, calendar, language='en',
- onlyAfter=None):
+ def outbound(self, txn, originator, recipient, calendar, onlyAfter=None):
"""
Generates and sends an outbound IMIP message.
@@ -473,7 +472,7 @@
msgId, message = self.generateEmail(inviteState, calendar, orgEmail,
orgCN, attendees, formattedFrom, addressWithToken, recipient,
- language=language)
+ language=self.language)
try:
success = (yield self.smtpSender.sendMessage(fromAddr, toAddr,
@@ -484,32 +483,6 @@
returnValue(False)
- def getIconPath(self, details, canceled, language='en'):
- iconDir = config.Scheduling.iMIP.MailIconsDirectory.rstrip("/")
-
- if canceled:
- iconName = "canceled.png"
- iconPath = os.path.join(iconDir, iconName)
- if os.path.exists(iconPath):
- return iconPath
- else:
- return None
-
- else:
- month = int(details['month'])
- day = int(details['day'])
- with translationTo(language) as trans:
- monthName = trans.monthAbbreviation(month)
- iconName = "%02d.png" % (day,)
- iconPath = os.path.join(iconDir, monthName.encode("utf-8"), iconName)
- if not os.path.exists(iconPath):
- # Try the generic (numeric) version
- iconPath = os.path.join(iconDir, "%02d" % (month,), iconName)
- if not os.path.exists(iconPath):
- return None
- return iconPath
-
-
def generateEmail(self, inviteState, calendar, orgEmail, orgCN,
attendees, fromAddress, replyToAddress, toAddress,
language='en'):
@@ -562,18 +535,16 @@
details = self.getEventDetails(calendar, language=language)
canceled = (calendar.propertyValue("METHOD") == "CANCEL")
- iconPath = self.getIconPath(details, canceled, language=language)
subjectFormat, labels = localizedLabels(language, canceled, inviteState)
details.update(labels)
details['subject'] = subjectFormat % {'summary' : details['summary']}
- details['iconName'] = iconName = "calicon.png"
plainText = self.renderPlainText(details, (orgCN, orgEmail),
attendees, canceled)
- [addIcon, htmlText] = self.renderHTML(details, (orgCN, orgEmail),
+ htmlText = self.renderHTML(details, (orgCN, orgEmail),
attendees, canceled)
msg = MIMEMultipart()
@@ -599,19 +570,6 @@
msgHtml = MIMEText(htmlText, "html", "UTF-8")
msgHtmlRelated.attach(msgHtml)
- # an image for html version
- if addIcon and iconPath != None and os.path.exists(iconPath):
-
- with open(iconPath) as iconFile:
- msgIcon = MIMEImage(iconFile.read(),
- _subtype='png;x-apple-mail-type=stationery;name="%s"' %
- (iconName,))
-
- msgIcon.add_header("Content-ID", "<%s>" % (iconName,))
- msgIcon.add_header("Content-Disposition", "inline;filename=%s" %
- (iconName,))
- msgHtmlRelated.attach(msgIcon)
-
calendarText = str(calendar)
# the icalendar attachment
self.log_debug("Mail gateway sending calendar body: %s"
@@ -663,10 +621,7 @@
Render HTML message part based on invitation details and a flag
indicating whether the message is a cancellation.
- @return: a 2-tuple of (should add icon (C{bool}), html text (C{str},
- representing utf-8 encoded bytes)). The first element indicates
- whether the MIME generator needs to add a C{cid:} icon image part to
- satisfy the HTML links.
+ @return: html text (C{str}, representing utf-8 encoded bytes)).
"""
orgCN, orgEmail = organizer
@@ -727,13 +682,9 @@
textCollector = []
flattenString(None, EmailElement()).addCallback(textCollector.append)
htmlText = textCollector[0]
+ return htmlText
- # If the template refers to an icon in a cid: link, it needs to be added
- # in the MIME.
- addIcon = (htmlTemplate.find("cid:%(iconName)s") != -1)
- return (addIcon, htmlText)
-
def getEventDetails(self, calendar, language='en'):
"""
Create a dictionary mapping slot names - specifically: summary,
Deleted: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/imip/resource.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/imip/resource.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/imip/resource.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -1,223 +0,0 @@
-##
-# Copyright (c) 2005-2013 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-from twext.python.log import Logger
-from twext.web2 import responsecode
-from twext.web2.dav.noneprops import NonePropertyStore
-from twext.web2.http import Response, HTTPError
-from twext.web2.http_headers import MimeType
-from twisted.internet.defer import succeed, inlineCallbacks, returnValue
-from twistedcaldav import caldavxml
-from twistedcaldav.config import config
-from twistedcaldav.directory.util import transactionFromRequest
-from twistedcaldav.ical import Component
-from twistedcaldav.localization import getLanguage
-from twistedcaldav.resource import CalDAVResource
-from twistedcaldav.scheduling.caldav.resource import deliverSchedulePrivilegeSet
-from twistedcaldav.scheduling.imip.scheduler import IMIPScheduler
-from txdav.xml import element as davxml
-
-__all__ = [
- "IMIPInboxResource",
- "IMIPReplyInboxResource",
- "IMIPInvitationInboxResource",
-]
-
-log = Logger()
-
-class IMIPInboxResource(CalDAVResource):
- """
- IMIP-delivery Inbox resource.
-
- Extends L{DAVResource} to provide IMIP delivery functionality.
- """
-
- def __init__(self, parent, store):
- """
- @param parent: the parent resource of this one.
- @param store: the store to use for transactions.
- """
- assert parent is not None
-
- CalDAVResource.__init__(
- self, principalCollections=parent.principalCollections()
- )
-
- self.parent = parent
- self._newStore = store
-
-
- def accessControlList(self, request, inheritance=True,
- expanding=False, inherited_aces=None):
-
- if not hasattr(self, "iMIPACL"):
- guid = config.Scheduling.iMIP.GUID
- self.iMIPACL = davxml.ACL(
- davxml.ACE(
- davxml.Principal(
- davxml.HRef.fromString("/principals/__uids__/%s/"
- % (guid,))
- ),
- davxml.Grant(
- davxml.Privilege(caldavxml.ScheduleDeliver()),
- ),
- ),
- )
-
- return succeed(self.iMIPACL)
-
-
- def resourceType(self):
- return davxml.ResourceType.ischeduleinbox
-
-
- def contentType(self):
- return MimeType.fromString("text/html; charset=utf-8")
-
-
- def isCollection(self):
- return False
-
-
- def isCalendarCollection(self):
- return False
-
-
- def isPseudoCalendarCollection(self):
- return False
-
-
- def deadProperties(self):
- if not hasattr(self, "_dead_properties"):
- self._dead_properties = NonePropertyStore(self)
- return self._dead_properties
-
-
- def etag(self):
- return succeed(None)
-
-
- def checkPreconditions(self, request):
- return None
-
-
- def render(self, request):
- output = """<html>
-<head>
-<title>IMIP Delivery Resource</title>
-</head>
-<body>
-<h1>IMIP Delivery Resource.</h1>
-</body
-</html>"""
-
- response = Response(200, {}, output)
- response.headers.setHeader("content-type", MimeType("text", "html"))
- return response
-
- ##
- # File
- ##
-
-
- def createSimilarFile(self, path):
- log.err("Attempt to create clone %r of resource %r" % (path, self))
- raise HTTPError(responsecode.NOT_FOUND)
-
- ##
- # ACL
- ##
-
-
- def defaultAccessControlList(self):
- privs = (
- davxml.Privilege(davxml.Read()),
- davxml.Privilege(caldavxml.ScheduleDeliver()),
- )
- if config.Scheduling.CalDAV.OldDraftCompatibility:
- privs += (davxml.Privilege(caldavxml.Schedule()),)
- return davxml.ACL(
- # DAV:Read, CalDAV:schedule-deliver for all principals (includes
- # anonymous)
- davxml.ACE(
- davxml.Principal(davxml.All()),
- davxml.Grant(*privs),
- davxml.Protected(),
- ),
- )
-
-
- def supportedPrivileges(self, request):
- return succeed(deliverSchedulePrivilegeSet)
-
-
-
-class IMIPReplyInboxResource(IMIPInboxResource):
-
- def renderHTTP(self, request):
- """
- Set up a transaction which will be used and committed by implicit
- scheduling.
- """
- self.transaction = transactionFromRequest(request, self._newStore)
- return super(IMIPReplyInboxResource, self).renderHTTP(request, self.transaction)
-
-
- @inlineCallbacks
- def http_POST(self, request):
- """
- The IMIP reply POST method (inbound)
- """
-
- # Check authentication and access controls
- yield self.authorize(request, (caldavxml.ScheduleDeliver(),))
-
- # Inject using the IMIPScheduler.
- scheduler = IMIPScheduler(request, self)
-
- # Do the POST processing treating this as a non-local schedule
- result = (yield scheduler.doSchedulingViaPOST(self.transaction, use_request_headers=True))
- returnValue(result.response())
-
-
-
-class IMIPInvitationInboxResource(IMIPInboxResource):
-
- def __init__(self, parent, store, mailer):
- super(IMIPInvitationInboxResource, self).__init__(parent, store)
- self.mailer = mailer
-
-
- @inlineCallbacks
- def http_POST(self, request):
- """
- The IMIP invitation POST method (outbound)
- """
-
- # Check authentication and access controls
- yield self.authorize(request, (caldavxml.ScheduleDeliver(),))
-
- # Compute token, add to db, generate email and send it
- calendar = (yield Component.fromIStream(request.stream))
- originator = request.headers.getRawHeaders("originator")[0]
- recipient = request.headers.getRawHeaders("recipient")[0]
- language = getLanguage(config)
-
- if not (yield self.mailer.outbound(originator,
- recipient, calendar, language=language)):
- returnValue(Response(code=responsecode.BAD_REQUEST))
-
- returnValue(Response(code=responsecode.OK))
Added: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/imip/test/test_inbound.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/imip/test/test_inbound.py (rev 0)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/imip/test/test_inbound.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,362 @@
+##
+# Copyright (c) 2008-2013 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+
+import email
+from twisted.internet.defer import inlineCallbacks
+from twisted.python.modules import getModule
+from twistedcaldav.ical import Component
+from twistedcaldav.scheduling.imip.inbound import MailReceiver
+from twistedcaldav.scheduling.imip.inbound import MailRetriever
+from twistedcaldav.scheduling.imip.inbound import injectMessage
+from twistedcaldav.scheduling.imip.inbound import IMIPReplyWork
+from twistedcaldav.scheduling.itip import iTIPRequestStatus
+from twistedcaldav.test.util import TestCase
+from twistedcaldav.test.util import xmlFile
+from txdav.common.datastore.test.util import buildStore
+from calendarserver.tap.util import getRootResource
+from twistedcaldav.config import config, ConfigDict
+
+
+class InboundTests(TestCase):
+
+ @inlineCallbacks
+ def setUp(self):
+ super(InboundTests, self).setUp()
+
+ self.store = yield buildStore(self, None)
+ self.patch(config.DirectoryService.params, "xmlFile", xmlFile)
+ self.root = getRootResource(config, self.store)
+ self.directory = self.root.getDirectory()
+ self.receiver = MailReceiver(self.store, self.directory)
+ self.retriever = MailRetriever(self.store, self.directory,
+ ConfigDict({
+ "Type" : "pop",
+ "UseSSL" : False,
+ "Server" : "example.com",
+ "Port" : 123,
+ })
+ )
+
+ def decorateTransaction(txn):
+ txn._rootResource = self.root
+ txn._mailRetriever = self.retriever
+
+ self.store.callWithNewTransactions(decorateTransaction)
+ module = getModule(__name__)
+ self.dataPath = module.filePath.sibling("data")
+
+ def dataFile(self, name):
+ """
+ Get the contents of a given data file from the 'data/mail' test
+ fixtures directory.
+ """
+ return self.dataPath.child(name).getContent()
+
+
+ def test_checkDSNFailure(self):
+
+ data = {
+ 'good_reply' : (False, None, None),
+ 'dsn_failure_no_original' : (True, 'failed', None),
+ 'dsn_failure_no_ics' : (True, 'failed', None),
+ 'dsn_failure_with_ics' : (True, 'failed', '''BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+METHOD:REQUEST
+PRODID:-//example Inc.//iCal 3.0//EN
+BEGIN:VTIMEZONE
+TZID:US/Pacific
+BEGIN:STANDARD
+DTSTART:20071104T020000
+RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
+TZNAME:PST
+TZOFFSETFROM:-0700
+TZOFFSETTO:-0800
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:20070311T020000
+RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
+TZNAME:PDT
+TZOFFSETFROM:-0800
+TZOFFSETTO:-0700
+END:DAYLIGHT
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:1E71F9C8-AEDA-48EB-98D0-76E898F6BB5C
+DTSTART;TZID=US/Pacific:20080812T094500
+DTEND;TZID=US/Pacific:20080812T104500
+ATTENDEE;CUTYPE=INDIVIDUAL;CN=User 01;PARTSTAT=ACCEPTED:mailto:user01 at exam
+ ple.com
+ATTENDEE;CUTYPE=INDIVIDUAL;RSVP=TRUE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-A
+ CTION;CN=nonexistant at example.com:mailto:nonexistant at example.com
+CREATED:20080812T191857Z
+DTSTAMP:20080812T191932Z
+ORGANIZER;CN=User 01:mailto:xyzzy+8e16b897-d544-4217-88e9-a363d08
+ 46f6c at example.com
+SEQUENCE:2
+SUMMARY:New Event
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
+'''),
+ }
+
+ for filename, expected in data.iteritems():
+ msg = email.message_from_string(self.dataFile(filename))
+ self.assertEquals(self.receiver.checkDSN(msg), expected)
+
+
+ @inlineCallbacks
+ def test_processDSN(self):
+
+ template = """BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+METHOD:REQUEST
+PRODID:-//example Inc.//iCal 3.0//EN
+BEGIN:VTIMEZONE
+TZID:US/Pacific
+BEGIN:DAYLIGHT
+DTSTART:20070311T020000
+RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
+TZNAME:PDT
+TZOFFSETFROM:-0800
+TZOFFSETTO:-0700
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20071104T020000
+RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
+TZNAME:PST
+TZOFFSETFROM:-0700
+TZOFFSETTO:-0800
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+UID:1E71F9C8-AEDA-48EB-98D0-76E898F6BB5C
+DTSTART;TZID=US/Pacific:20080812T094500
+DTEND;TZID=US/Pacific:20080812T104500
+ATTENDEE;CUTYPE=INDIVIDUAL;CN=User 01;PARTSTAT=ACCEPTED:mailto:user01 at exam
+ ple.com
+ATTENDEE;CUTYPE=INDIVIDUAL;RSVP=TRUE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-A
+ CTION;CN=nonexistant at example.com:mailto:nonexistant at example.com
+CREATED:20080812T191857Z
+DTSTAMP:20080812T191932Z
+ORGANIZER;CN=User 01:mailto:xyzzy+%s at example.com
+SEQUENCE:2
+SUMMARY:New Event
+TRANSP:OPAQUE
+END:VEVENT
+END:VCALENDAR
+"""
+
+ # Make sure an unknown token is not processed
+ calBody = template % "bogus_token"
+ self.assertEquals(
+ (yield self.receiver.processDSN(calBody, "xyzzy")),
+ MailReceiver.UNKNOWN_TOKEN
+ )
+
+ # Make sure a known token *is* processed
+ txn = self.store.newTransaction()
+ token = (yield txn.imipCreateToken(
+ "urn:uuid:5A985493-EE2C-4665-94CF-4DFEA3A89500",
+ "mailto:user02 at example.com",
+ "1E71F9C8-AEDA-48EB-98D0-76E898F6BB5C"
+ ))
+ yield txn.commit()
+ calBody = template % token
+ result = (yield self.receiver.processDSN(calBody, "xyzzy"))
+ self.assertEquals(result, MailReceiver.INJECTION_SUBMITTED)
+
+
+ @inlineCallbacks
+ def test_processReply(self):
+ msg = email.message_from_string(self.dataFile('good_reply'))
+
+ # Make sure an unknown token is not processed
+ result = (yield self.receiver.processReply(msg))
+ self.assertEquals(result, MailReceiver.UNKNOWN_TOKEN)
+
+ # Make sure a known token *is* processed
+ txn = self.store.newTransaction()
+ yield txn.imipCreateToken(
+ "urn:uuid:5A985493-EE2C-4665-94CF-4DFEA3A89500",
+ "mailto:xyzzy at example.com",
+ "1E71F9C8-AEDA-48EB-98D0-76E898F6BB5C",
+ token="d7cdf68d-8b73-4df1-ad3b-f08002fb285f"
+ )
+ yield txn.commit()
+
+ result = (yield self.receiver.processReply(msg))
+ self.assertEquals(result, MailReceiver.INJECTION_SUBMITTED)
+
+
+ def test_processReplyMissingOrganizer(self):
+ msg = email.message_from_string(self.dataFile('reply_missing_organizer'))
+
+ # stick the token in the database first
+ txn = self.store.newTransaction()
+ yield txn.imipCreateToken(
+ "urn:uuid:5A985493-EE2C-4665-94CF-4DFEA3A89500",
+ "mailto:xyzzy at example.com",
+ "1E71F9C8-AEDA-48EB-98D0-76E898F6BB5C",
+ token="d7cdf68d-8b73-4df1-ad3b-f08002fb285f"
+ )
+ yield txn.commit()
+
+ result = (yield self.receiver.processReply(msg))
+ organizer, _ignore_attendee, calendar = result
+ organizerProp = calendar.mainComponent().getOrganizerProperty()
+ self.assertTrue(organizerProp is not None)
+ self.assertEquals(organizer,
+ "urn:uuid:5A985493-EE2C-4665-94CF-4DFEA3A89500")
+
+
+ def test_processReplyMissingAttendee(self):
+ msg = email.message_from_string(self.dataFile('reply_missing_attendee'))
+
+ txn = self.store.newTransaction()
+ yield txn.imipCreateToken(
+ "urn:uuid:5A985493-EE2C-4665-94CF-4DFEA3A89500",
+ "mailto:xyzzy at example.com",
+ "1E71F9C8-AEDA-48EB-98D0-76E898F6BB5C",
+ token="d7cdf68d-8b73-4df1-ad3b-f08002fb285f"
+ )
+ yield txn.commit()
+
+ result = (yield self.receiver.processReply(msg))
+ _ignore_organizer, attendee, calendar = result
+
+ # Since the expected attendee was missing, the reply processor should
+ # have added an attendee back in with a "5.1;Service unavailable"
+ # schedule-status
+ attendeeProp = calendar.mainComponent().getAttendeeProperty([attendee])
+ self.assertEquals(attendeeProp.parameterValue("SCHEDULE-STATUS"),
+ iTIPRequestStatus.SERVICE_UNAVAILABLE)
+
+
+ def test_processReplyMissingAttachment(self):
+
+ msg = email.message_from_string(
+ self.dataFile('reply_missing_attachment')
+ )
+
+ # stick the token in the database first
+ txn = self.store.newTransaction()
+ yield txn.imipCreateToken(
+ "urn:uuid:5A985493-EE2C-4665-94CF-4DFEA3A89500",
+ "mailto:xyzzy at example.com",
+ "1E71F9C8-AEDA-48EB-98D0-76E898F6BB5C",
+ token="d7cdf68d-8b73-4df1-ad3b-f08002fb285f"
+ )
+ yield txn.commit()
+
+ result = (yield self.receiver.processReply(msg))
+ self.assertEquals(result, MailReceiver.REPLY_FORWARDED_TO_ORGANIZER)
+
+ @inlineCallbacks
+ def test_injectMessage(self):
+
+ calendar = Component.fromString("""BEGIN:VCALENDAR
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+VERSION:2.0
+METHOD:REPLY
+BEGIN:VEVENT
+UID:12345-67890
+DTSTAMP:20130208T120000Z
+DTSTART:20180601T120000Z
+DTEND:20180601T130000Z
+ORGANIZER:urn:uuid:user01
+ATTENDEE:mailto:xyzzy at example.com;PARTSTAT=ACCEPTED
+END:VEVENT
+END:VCALENDAR
+""")
+
+ txn = self.store.newTransaction()
+ result = (yield injectMessage(
+ txn,
+ self.root,
+ "urn:uuid:user01",
+ "mailto:xyzzy at example.com",
+ calendar
+ )
+ )
+ yield txn.commit()
+ self.assertEquals(
+ "1.2;Scheduling message has been delivered",
+ result.responses[0].children[1].toString()
+ )
+
+ @inlineCallbacks
+ def test_injectMessageWithError(self):
+
+ calendar = Component.fromString("""BEGIN:VCALENDAR
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+VERSION:2.0
+METHOD:REPLY
+BEGIN:VEVENT
+UID:12345-67890
+DTSTAMP:20130208T120000Z
+DTSTART:20180601T120000Z
+DTEND:20180601T130000Z
+ORGANIZER:urn:uuid:unknown_user
+ATTENDEE:mailto:xyzzy at example.com;PARTSTAT=ACCEPTED
+END:VEVENT
+END:VCALENDAR
+""")
+
+ txn = self.store.newTransaction()
+ result = (yield injectMessage(
+ txn,
+ self.root,
+ "urn:uuid:unknown_user",
+ "mailto:xyzzy at example.com",
+ calendar
+ )
+ )
+ yield txn.commit()
+ self.assertEquals(
+ "3.7;Invalid Calendar User",
+ result.responses[0].children[1].toString()
+ )
+
+
+ @inlineCallbacks
+ def test_work(self):
+
+ calendar = """BEGIN:VCALENDAR
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+VERSION:2.0
+METHOD:REPLY
+BEGIN:VEVENT
+UID:12345-67890
+DTSTAMP:20130208T120000Z
+DTSTART:20180601T120000Z
+DTEND:20180601T130000Z
+ORGANIZER:urn:uuid:user01
+ATTENDEE:mailto:xyzzy at example.com;PARTSTAT=ACCEPTED
+END:VEVENT
+END:VCALENDAR
+"""
+ txn = self.store.newTransaction()
+ wp = (yield txn.enqueue(IMIPReplyWork,
+ organizer="urn:uuid:user01",
+ attendee="mailto:xyzzy at example.com",
+ icalendarText=calendar
+ ))
+ yield txn.commit()
+ yield wp.whenExecuted()
Added: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/imip/test/test_outbound.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/imip/test/test_outbound.py (rev 0)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/imip/test/test_outbound.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,556 @@
+##
+# Copyright (c) 2008-2013 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+from __future__ import print_function
+
+from cStringIO import StringIO
+import os
+
+import email
+from pycalendar.datetime import PyCalendarDateTime
+from twisted.internet.defer import inlineCallbacks, succeed
+from twisted.web.template import Element, renderer, flattenString
+from twistedcaldav.config import config
+from twistedcaldav.directory import augment
+from twistedcaldav.directory.xmlfile import XMLDirectoryService
+from twistedcaldav.ical import Component
+from twistedcaldav.scheduling.imip.outbound import IMIPInvitationWork
+from twistedcaldav.scheduling.imip.outbound import MailSender
+from twistedcaldav.scheduling.imip.outbound import StringFormatTemplateLoader
+from twistedcaldav.test.util import TestCase, xmlFile, augmentsFile
+from txdav.common.datastore.test.util import buildStore
+
+initialInviteText = u"""BEGIN:VCALENDAR
+VERSION:2.0
+METHOD:REQUEST
+BEGIN:VEVENT
+UID:CFDD5E46-4F74-478A-9311-B3FF905449C3
+DTSTART:20200325T154500Z
+DTEND:20200325T164500Z
+ATTENDEE;CN=Th\xe9 Attendee;CUTYPE=INDIVIDUAL;PARTSTAT=NEEDS-ACTION;RSVP=TRU
+ E:mailto:attendee at example.com
+ATTENDEE;CN=Th\xe9 Organizer;CUTYPE=INDIVIDUAL;EMAIL=organizer at example.com;P
+ ARTSTAT=ACCEPTED:urn:uuid:C3B38B00-4166-11DD-B22C-A07C87E02F6A
+ATTENDEE;CN=An Attendee without CUTYPE;EMAIL=nocutype at example.com;PARTSTAT=A
+ CCEPTED:urn:uuid:4DB528DC-3E60-44FA-9546-2A00FCDCFFAB
+ATTENDEE;EMAIL=nocn at example.com;PARTSTAT=ACCEPTED:urn:uuid:A592CF8B-4FC8-4E4
+ F-B543-B2F29A7EEB0B
+ORGANIZER;CN=Th\xe9 Organizer;EMAIL=organizer at example.com:urn:uuid:C3B38B00-
+ 4166-11DD-B22C-A07C87E02F6A
+SUMMARY:t\xe9sting outbound( )
+DESCRIPTION:awesome description with "<" and "&"
+END:VEVENT
+END:VCALENDAR
+"""
+
+ORGANIZER = "urn:uuid:C3B38B00-4166-11DD-B22C-A07C87E02F6A"
+ATTENDEE = "mailto:attendee at example.com"
+ICALUID = "CFDD5E46-4F74-478A-9311-B3FF905449C3"
+
+class DummySMTPSender(object):
+
+ def __init__(self):
+ self.reset()
+ self.shouldSucceed = True
+
+ def reset(self):
+ self.sendMessageCalled = False
+ self.fromAddr = None
+ self.toAddr = None
+ self.msgId = None
+ self.message = None
+
+ def sendMessage(self, fromAddr, toAddr, msgId, message):
+ self.sendMessageCalled = True
+ self.fromAddr = fromAddr
+ self.toAddr = toAddr
+ self.msgId = msgId
+ self.message = message
+ return succeed(self.shouldSucceed)
+
+
+class OutboundTests(TestCase):
+
+ @inlineCallbacks
+ def setUp(self):
+ self.store = yield buildStore(self, None)
+ self.directory = XMLDirectoryService(
+ {
+ 'xmlFile' : xmlFile,
+ 'augmentService' :
+ augment.AugmentXMLDB(xmlFiles=(augmentsFile.path,)),
+ }
+ )
+ self.sender = MailSender("server at example.com", 7, DummySMTPSender(),
+ language="en")
+
+ def _getSender(ignored):
+ return self.sender
+ self.patch(IMIPInvitationWork, "getMailSender", _getSender)
+
+ self.wp = None
+ self.store.queuer.callWithNewProposals(self._proposalCallback)
+
+ def _proposalCallback(self, wp):
+ self.wp = wp
+
+ @inlineCallbacks
+ def test_work(self):
+ txn = self.store.newTransaction()
+ wp = (yield txn.enqueue(IMIPInvitationWork,
+ fromAddr=ORGANIZER,
+ toAddr=ATTENDEE,
+ icalendarText=initialInviteText.replace("\n", "\r\n"),
+ ))
+ self.assertEquals(wp, self.wp)
+ yield txn.commit()
+ yield wp.whenExecuted()
+
+ txn = self.store.newTransaction()
+ token = (yield txn.imipGetToken(
+ ORGANIZER,
+ ATTENDEE,
+ ICALUID
+ ))
+ self.assertTrue(token)
+ organizer, attendee, icaluid = (yield txn.imipLookupByToken(token))[0]
+ yield txn.commit()
+ self.assertEquals(organizer, ORGANIZER)
+ self.assertEquals(attendee, ATTENDEE)
+ self.assertEquals(icaluid, ICALUID)
+
+ @inlineCallbacks
+ def test_workFailure(self):
+ self.sender.smtpSender.shouldSucceed = False
+
+ txn = self.store.newTransaction()
+ wp = (yield txn.enqueue(IMIPInvitationWork,
+ fromAddr=ORGANIZER,
+ toAddr=ATTENDEE,
+ icalendarText=initialInviteText.replace("\n", "\r\n"),
+ ))
+ yield txn.commit()
+ yield wp.whenExecuted()
+ # Verify a new work proposal was not created
+ self.assertEquals(wp, self.wp)
+
+
+ def _interceptEmail(self, inviteState, calendar, orgEmail, orgCn,
+ attendees, fromAddress, replyToAddress, toAddress, language="en"):
+ self.inviteState = inviteState
+ self.calendar = calendar
+ self.orgEmail = orgEmail
+ self.orgCn = orgCn
+ self.attendees = attendees
+ self.fromAddress = fromAddress
+ self.replyToAddress = replyToAddress
+ self.toAddress = toAddress
+ self.language = language
+ self.results = self._actualGenerateEmail(inviteState, calendar,
+ orgEmail, orgCn, attendees, fromAddress, replyToAddress, toAddress,
+ language=language)
+ return self.results
+
+ @inlineCallbacks
+ def test_outbound(self):
+ """
+ Make sure outbound( ) stores tokens properly so they can be looked up
+ """
+
+ config.Scheduling.iMIP.Sending.Address = "server at example.com"
+ self.patch(config.Localization, "LocalesDirectory", os.path.join(os.path.dirname(__file__), "locales"))
+ self._actualGenerateEmail = self.sender.generateEmail
+ self.patch(self.sender, "generateEmail", self._interceptEmail)
+
+ data = (
+ # Initial invite
+ (
+ initialInviteText,
+ "CFDD5E46-4F74-478A-9311-B3FF905449C3",
+ "urn:uuid:C3B38B00-4166-11DD-B22C-A07C87E02F6A",
+ "mailto:attendee at example.com",
+ "new",
+ "organizer at example.com",
+ u"Th\xe9 Organizer",
+ [
+ (u'Th\xe9 Attendee', u'attendee at example.com'),
+ (u'Th\xe9 Organizer', u'organizer at example.com'),
+ (u'An Attendee without CUTYPE', u'nocutype at example.com'),
+ (None, u'nocn at example.com'),
+ ],
+ u"Th\xe9 Organizer <organizer at example.com>",
+ "=?utf-8?q?Th=C3=A9_Organizer_=3Corganizer=40example=2Ecom=3E?=",
+ "attendee at example.com",
+ ),
+
+ # Update
+ (
+ """BEGIN:VCALENDAR
+VERSION:2.0
+METHOD:REQUEST
+BEGIN:VEVENT
+UID:CFDD5E46-4F74-478A-9311-B3FF905449C3
+DTSTART:20100325T154500Z
+DTEND:20100325T164500Z
+ATTENDEE;CN=The Attendee;CUTYPE=INDIVIDUAL;PARTSTAT=NEEDS-ACTION;RSVP=TRUE:
+ mailto:attendee at example.com
+ATTENDEE;CN=The Organizer;CUTYPE=INDIVIDUAL;EMAIL=organizer at example.com;PAR
+ TSTAT=ACCEPTED:urn:uuid:C3B38B00-4166-11DD-B22C-A07C87E02F6A
+ORGANIZER;CN=The Organizer;EMAIL=organizer at example.com:urn:uuid:C3B38B00-41
+ 66-11DD-B22C-A07C87E02F6A
+SUMMARY:testing outbound( ) *update*
+END:VEVENT
+END:VCALENDAR
+""",
+ "CFDD5E46-4F74-478A-9311-B3FF905449C3",
+ "urn:uuid:C3B38B00-4166-11DD-B22C-A07C87E02F6A",
+ "mailto:attendee at example.com",
+ "update",
+ "organizer at example.com",
+ "The Organizer",
+ [
+ (u'The Attendee', u'attendee at example.com'),
+ (u'The Organizer', u'organizer at example.com')
+ ],
+ "The Organizer <organizer at example.com>",
+ "The Organizer <organizer at example.com>",
+ "attendee at example.com",
+ ),
+
+ # Reply
+ (
+ """BEGIN:VCALENDAR
+VERSION:2.0
+METHOD:REPLY
+BEGIN:VEVENT
+UID:DFDD5E46-4F74-478A-9311-B3FF905449C4
+DTSTART:20100325T154500Z
+DTEND:20100325T164500Z
+ATTENDEE;CN=The Attendee;CUTYPE=INDIVIDUAL;EMAIL=attendee at example.com;PARTST
+ AT=ACCEPTED:urn:uuid:C3B38B00-4166-11DD-B22C-A07C87E02F6A
+ORGANIZER;CN=The Organizer;EMAIL=organizer at example.com:mailto:organizer at exam
+ ple.com
+SUMMARY:testing outbound( ) *reply*
+END:VEVENT
+END:VCALENDAR
+""",
+ None,
+ "urn:uuid:C3B38B00-4166-11DD-B22C-A07C87E02F6A",
+ "mailto:organizer at example.com",
+ "reply",
+ "organizer at example.com",
+ "The Organizer",
+ [
+ (u'The Attendee', u'attendee at example.com'),
+ ],
+ "attendee at example.com",
+ "attendee at example.com",
+ "organizer at example.com",
+ ),
+
+ )
+ for (inputCalendar, UID, inputOriginator, inputRecipient, inviteState,
+ outputOrganizerEmail, outputOrganizerName, outputAttendeeList,
+ outputFrom, encodedFrom, outputRecipient) in data:
+
+ txn = self.store.newTransaction()
+ yield self.sender.outbound(
+ txn,
+ inputOriginator,
+ inputRecipient,
+ Component.fromString(inputCalendar.replace("\n", "\r\n")),
+ onlyAfter=PyCalendarDateTime(2010, 1, 1, 0, 0, 0)
+ )
+ yield txn.commit()
+
+ msg = email.message_from_string(self.sender.smtpSender.message)
+ self.assertEquals(msg["From"], encodedFrom)
+ self.assertEquals(self.inviteState, inviteState)
+ self.assertEquals(self.orgEmail, outputOrganizerEmail)
+ self.assertEquals(self.orgCn, outputOrganizerName)
+ self.assertEquals(self.attendees, outputAttendeeList)
+ self.assertEquals(self.fromAddress, outputFrom)
+ self.assertEquals(self.toAddress, outputRecipient)
+
+ if UID: # The organizer is local, and server is sending to remote
+ # attendee
+ txn = self.store.newTransaction()
+ token = (yield txn.imipGetToken(inputOriginator, inputRecipient,
+ UID))
+ yield txn.commit()
+ self.assertNotEquals(token, None)
+ self.assertEquals(msg["Reply-To"],
+ "server+%s at example.com" % (token,))
+
+ # Make sure attendee property for organizer exists and matches
+ # the CUA of the organizer property
+ orgValue = self.calendar.getOrganizerProperty().value()
+ self.assertEquals(
+ orgValue,
+ self.calendar.getAttendeeProperty([orgValue]).value()
+ )
+
+ else: # Reply only -- the attendee is local, and server is sending reply to remote organizer
+
+ self.assertEquals(msg["Reply-To"], self.fromAddress)
+
+ # Check that we don't send any messages for events completely in
+ # the past.
+ self.sender.smtpSender.reset()
+ txn = self.store.newTransaction()
+ yield self.sender.outbound(
+ txn,
+ inputOriginator,
+ inputRecipient,
+ Component.fromString(inputCalendar.replace("\n", "\r\n")),
+ onlyAfter=PyCalendarDateTime(2021, 1, 1, 0, 0, 0)
+ )
+ yield txn.commit()
+ self.assertFalse(self.sender.smtpSender.sendMessageCalled)
+
+
+ @inlineCallbacks
+ def test_tokens(self):
+ txn = self.store.newTransaction()
+ token = (yield txn.imipLookupByToken("xyzzy"))
+ yield txn.commit()
+ self.assertEquals(token, [])
+
+ txn = self.store.newTransaction()
+ token1 = (yield txn.imipCreateToken("organizer", "attendee", "icaluid"))
+ yield txn.commit()
+
+ txn = self.store.newTransaction()
+ token2 = (yield txn.imipGetToken("organizer", "attendee", "icaluid"))
+ yield txn.commit()
+ self.assertEquals(token1, token2)
+
+ txn = self.store.newTransaction()
+ self.assertEquals((yield txn.imipLookupByToken(token1)),
+ [["organizer", "attendee", "icaluid"]])
+ yield txn.commit()
+
+ txn = self.store.newTransaction()
+ yield txn.imipRemoveToken(token1)
+ yield txn.commit()
+
+ txn = self.store.newTransaction()
+ self.assertEquals((yield txn.imipLookupByToken(token1)), [])
+ yield txn.commit()
+
+
+ @inlineCallbacks
+ def test_mailtoTokens(self):
+ """
+ Make sure old mailto tokens are still honored
+ """
+
+ organizerEmail = "mailto:organizer at example.com"
+
+ # Explictly store a token with mailto: CUA for organizer
+ # (something that doesn't happen any more, but did in the past)
+ txn = self.store.newTransaction()
+ origToken = (yield txn.imipCreateToken(organizerEmail,
+ "mailto:attendee at example.com",
+ "CFDD5E46-4F74-478A-9311-B3FF905449C3"
+ )
+ )
+ yield txn.commit()
+
+ inputCalendar = initialInviteText
+ UID = "CFDD5E46-4F74-478A-9311-B3FF905449C3"
+ inputOriginator = "urn:uuid:C3B38B00-4166-11DD-B22C-A07C87E02F6A"
+ inputRecipient = "mailto:attendee at example.com"
+
+ txn = self.store.newTransaction()
+ yield self.sender.outbound(txn, inputOriginator, inputRecipient,
+ Component.fromString(inputCalendar.replace("\n", "\r\n")),
+ onlyAfter=PyCalendarDateTime(2010, 1, 1, 0, 0, 0))
+
+ # Verify we didn't create a new token...
+ txn = self.store.newTransaction()
+ token = (yield txn.imipGetToken(inputOriginator, inputRecipient, UID))
+ yield txn.commit()
+ self.assertEquals(token, None)
+
+ # But instead kept the old one...
+ txn = self.store.newTransaction()
+ token = (yield txn.imipGetToken(organizerEmail, inputRecipient, UID))
+ yield txn.commit()
+ self.assertEquals(token, origToken)
+
+
+ def generateSampleEmail(self):
+ """
+ Invoke L{MailHandler.generateEmail} and parse the result.
+ """
+ calendar = Component.fromString(initialInviteText)
+ msgID, msgTxt = self.sender.generateEmail(
+ inviteState='new',
+ calendar=calendar,
+ orgEmail=u"user01 at localhost",
+ orgCN=u"User Z\xe9ro One",
+ attendees=[(u"Us\xe9r One", "user01 at localhost"),
+ (u"User 2", "user02 at localhost")],
+ fromAddress="user01 at localhost",
+ replyToAddress="imip-system at localhost",
+ toAddress="user03 at localhost",
+ )
+ message = email.message_from_string(msgTxt)
+ return msgID, message
+
+
+ def test_generateEmail(self):
+ """
+ L{MailHandler.generateEmail} generates a MIME-formatted email with a
+ text/plain part, a text/html part, and a text/calendar part.
+ """
+ msgID, message = self.generateSampleEmail()
+ self.assertEquals(message['Message-ID'], msgID)
+ expectedTypes = set(["text/plain", "text/html", "text/calendar"])
+ actualTypes = set([
+ part.get_content_type() for part in message.walk()
+ if part.get_content_type().startswith("text/")
+ ])
+ self.assertEquals(actualTypes, expectedTypes)
+
+
+ def test_emailEncoding(self):
+ """
+ L{MailHandler.generateEmail} will preserve any non-ASCII characters
+ present in the fields that it formats in the message body.
+ """
+ _ignore_msgID, message = self.generateSampleEmail()
+ textPart = partByType(message, "text/plain")
+ htmlPart = partByType(message, "text/html")
+
+ plainText = textPart.get_payload(decode=True).decode(
+ textPart.get_content_charset()
+ )
+ htmlText = htmlPart.get_payload(decode=True).decode(
+ htmlPart.get_content_charset()
+ )
+
+ self.assertIn(u"Us\u00e9r One", plainText)
+ self.assertIn(u'<a href="mailto:user01 at localhost">Us\u00e9r One</a>',
+ htmlText)
+
+ # The same assertion, but with the organizer's form.
+ self.assertIn(
+ u'<a href="mailto:user01 at localhost">User Z\u00e9ro One</a>',
+ htmlText)
+
+
+ def test_emailQuoting(self):
+ """
+ L{MailHandler.generateEmail} will HTML-quote all relevant fields in the
+ HTML part, but not the text/plain part.
+ """
+ _ignore_msgID, message = self.generateSampleEmail()
+ htmlPart = partByType(message, "text/html").get_payload(decode=True)
+ plainPart = partByType(message, "text/plain").get_payload(decode=True)
+ expectedPlain = 'awesome description with "<" and "&"'
+ expectedHTML = expectedPlain.replace("&", "&").replace("<", "<")
+
+ self.assertIn(expectedPlain, plainPart)
+ self.assertIn(expectedHTML, htmlPart)
+
+
+ def test_stringFormatTemplateLoader(self):
+ """
+ L{StringFormatTemplateLoader.load} will convert a template with
+ C{%(x)s}-format slots by converting it to a template with C{<t:slot
+ name="x" />} slots, and a renderer on the document element named
+ according to the constructor argument.
+ """
+ class StubElement(Element):
+ loader = StringFormatTemplateLoader(
+ lambda : StringIO(
+ "<test><alpha>%(slot1)s</alpha>%(other)s</test>"
+ ),
+ "testRenderHere"
+ )
+
+ @renderer
+ def testRenderHere(self, request, tag):
+ return tag.fillSlots(slot1="hello",
+ other="world")
+ result = []
+ flattenString(None, StubElement()).addCallback(result.append)
+ self.assertEquals(result,
+ ["<test><alpha>hello</alpha>world</test>"])
+
+
+ def test_templateLoaderWithAttributes(self):
+ """
+ L{StringFormatTemplateLoader.load} will convert a template with
+ C{%(x)s}-format slots inside attributes into t:attr elements containing
+ t:slot slots.
+ """
+ class StubElement(Element):
+ loader = StringFormatTemplateLoader(
+ lambda : StringIO(
+ '<test><alpha beta="before %(slot1)s after">inner</alpha>'
+ '%(other)s</test>'
+ ),
+ "testRenderHere"
+ )
+
+ @renderer
+ def testRenderHere(self, request, tag):
+ return tag.fillSlots(slot1="hello",
+ other="world")
+ result = []
+ flattenString(None, StubElement()).addCallback(result.append)
+ self.assertEquals(result,
+ ['<test><alpha beta="before hello after">'
+ 'inner</alpha>world</test>'])
+
+
+ def test_templateLoaderTagSoup(self):
+ """
+ L{StringFormatTemplateLoader.load} will convert a template with
+ C{%(x)s}-format slots into t:slot slots, and render a well-formed output
+ document, even if the input is malformed (i.e. missing necessary closing
+ tags).
+ """
+ class StubElement(Element):
+ loader = StringFormatTemplateLoader(
+ lambda : StringIO(
+ '<test><alpha beta="before %(slot1)s after">inner</alpha>'
+ '%(other)s'
+ ),
+ "testRenderHere"
+ )
+
+ @renderer
+ def testRenderHere(self, request, tag):
+ return tag.fillSlots(slot1="hello",
+ other="world")
+ result = []
+ flattenString(None, StubElement()).addCallback(result.append)
+ self.assertEquals(result,
+ ['<test><alpha beta="before hello after">'
+ 'inner</alpha>world</test>'])
+
+def partByType(message, contentType):
+ """
+ Retrieve a MIME part from an L{email.message.Message} based on a content
+ type.
+ """
+ for part in message.walk():
+ if part.get_content_type() == contentType:
+ return part
+ raise KeyError(contentType)
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/implicit.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/implicit.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/implicit.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -597,6 +597,9 @@
for rid in self.needs_action_rids:
comp = self.calendar.overriddenComponent(rid)
+ if comp is None:
+ comp = self.calendar.deriveInstance(rid)
+ self.calendar.addComponent(comp)
for attendee in comp.getAllAttendeeProperties():
if attendee.hasParameter("PARTSTAT"):
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/itip.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/itip.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/itip.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -332,7 +332,7 @@
new_master = itip_message.masterComponent()
attendees = set()
rids = set()
- if new_master:
+ if new_master is not None and old_master is not None:
attendee, partstat, private_comment = iTipProcessing.updateAttendeeData(new_master, old_master)
if attendee:
attendees.add(attendee)
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/processing.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/processing.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/processing.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -560,8 +560,9 @@
send_reply = False
store_inbox = True
- # Let the store know that no time-range info has changed for a refresh
- if hasattr(self.request, "doing_attendee_refresh"):
+ # Let the store know that no time-range info has changed for a refresh (assuming that
+ # no auto-accept changes were made)
+ if hasattr(self.request, "doing_attendee_refresh") and not send_reply:
new_calendar.noInstanceIndexing = True
# Update the attendee's copy of the event
@@ -761,17 +762,32 @@
cuas = self.recipient.principal.calendarUserAddresses()
# First expand current one to get instances (only go 1 year into the future)
- default_future_expansion_duration = PyCalendarDuration(days=365)
+ default_future_expansion_duration = PyCalendarDuration(days=config.Scheduling.Options.AutoSchedule.FutureFreeBusyDays)
expand_max = PyCalendarDateTime.getToday() + default_future_expansion_duration
instances = calendar.expandTimeRanges(expand_max, ignoreInvalidInstances=True)
+ # We are goin g to ignore auto-accept processing for anything more than a day old (actually use -2 days
+ # to add some slop to account for possible timezone offsets)
+ min_date = PyCalendarDateTime.getToday()
+ min_date.offsetDay(-2)
+ allOld = True
+
# Cache the current attendee partstat on the instance object for later use, and
# also mark whether the instance time slot would be free
for instance in instances.instances.itervalues():
attendee = instance.component.getAttendeeProperty(cuas)
instance.partstat = attendee.parameterValue("PARTSTAT", "NEEDS-ACTION") if attendee else None
instance.free = True
+ instance.active = (instance.end > min_date)
+ if instance.active:
+ allOld = False
+ # If every instance is in the past we punt right here so we don't waste time on freebusy lookups etc.
+ # There will be no auto-accept and no inbox item stored (so as not to waste storage on items that will
+ # never be processed).
+ if allOld:
+ returnValue((False, False, "",))
+
# Extract UID from primary component as we want to ignore this one if we match it
# in any calendars.
comp = calendar.mainComponent(allow_multiple=True)
@@ -795,7 +811,7 @@
# Now do search for overlapping time-range and set instance.free based
# on whether there is an overlap or not
for instance in instances.instances.itervalues():
- if instance.partstat == "NEEDS-ACTION" and instance.free:
+ if instance.partstat == "NEEDS-ACTION" and instance.free and instance.active:
try:
# First list is BUSY, second BUSY-TENTATIVE, third BUSY-UNAVAILABLE
fbinfo = ([], [], [])
@@ -829,10 +845,11 @@
break
# Now adjust the instance.partstat currently set to "NEEDS-ACTION" to the
- # value determined by auto-accept logic based on instance.free state
+ # value determined by auto-accept logic based on instance.free state. However,
+ # ignore any instance in the past - leave them as NEEDS-ACTION.
partstat_counts = collections.defaultdict(int)
for instance in instances.instances.itervalues():
- if instance.partstat == "NEEDS-ACTION":
+ if instance.partstat == "NEEDS-ACTION" and instance.active:
if automode == "accept-always":
freePartstat = busyPartstat = "ACCEPTED"
elif automode == "decline-always":
@@ -845,14 +862,14 @@
if len(partstat_counts) == 0:
# Nothing to do
- returnValue((False, True, "",))
+ returnValue((False, False, "",))
elif len(partstat_counts) == 1:
# Do the simple case of all PARTSTATs the same separately
# Extract the ATTENDEE property matching current recipient from the calendar data
attendeeProps = calendar.getAttendeeProperties(cuas)
if not attendeeProps:
- returnValue((False, True, "",))
+ returnValue((False, False, "",))
made_changes = False
partstat = partstat_counts.keys()[0]
@@ -861,7 +878,7 @@
store_inbox = partstat == "NEEDS-ACTION"
else:
- # Hard case: some accepted some declined
+ # Hard case: some accepted, some declined, some needs-action
# What we will do is mark any master instance as accepted, then mark each existing
# overridden instance as accepted or declined, and generate new overridden instances for
# any other declines.
@@ -894,7 +911,7 @@
if overridden:
# Change ATTENDEE property to match new state
- if instance.partstat == "NEEDS-ACTION":
+ if instance.partstat == "NEEDS-ACTION" and instance.active:
store_inbox = True
made_changes |= self.resetAttendeePartstat(overridden, cuas, instance.partstat)
else:
@@ -904,7 +921,7 @@
if derived:
attendee = derived.getAttendeeProperty(cuas)
if attendee:
- if instance.partstat == "NEEDS-ACTION":
+ if instance.partstat == "NEEDS-ACTION" and instance.active:
store_inbox = True
self.resetAttendeePartstat(derived, cuas, instance.partstat, hadMasterRsvp)
made_changes = True
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/test/test_icaldiff.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/test/test_icaldiff.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/test/test_icaldiff.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -2014,6 +2014,17 @@
PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
BEGIN:VEVENT
UID:12345-67890
+RECURRENCE-ID:20080601T120000Z
+DTSTART:20080601T120000Z
+DTEND:20080601T130000Z
+ATTENDEE:mailto:user1 at example.com
+ATTENDEE;PARTSTAT=DECLINED;RSVP=TRUE:mailto:user2 at example.com
+ORGANIZER;CN=User 01:mailto:user1 at example.com
+TRANSP:TRANSPARENT
+X-CALENDARSERVER-HIDDEN-INSTANCE:T
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890
RECURRENCE-ID:20080604T120000Z
DTSTART:20080604T130000Z
DTEND:20080604T140000Z
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/test/test_itip.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/test/test_itip.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/test/test_itip.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,6 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
from pycalendar.datetime import PyCalendarDateTime
from pycalendar.timezone import PyCalendarTimezone
@@ -26,6 +27,210 @@
iCalendar support tests
"""
+ def test_processReply(self):
+ """
+ Test iTIPProcessing.processReply
+ """
+
+ data = (
+ (
+ "1.1 Simple Reply - non recurring",
+ """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890-1
+DTSTART:20071114T000000Z
+DTSTAMP:20071114T000000Z
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user02 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+ """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+METHOD:REPLY
+BEGIN:VEVENT
+UID:12345-67890-1
+DTSTART:20071115T000000Z
+DTSTAMP:20071114T000000Z
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED:mailto:user02 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+ """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890-1
+DTSTART:20071114T000000Z
+DTSTAMP:20071114T000000Z
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0:mailto:user02 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+ True,
+ ),
+ (
+ "1.2 Simple Reply - recurring no overrides",
+ """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890-1
+DTSTART:20071114T000000Z
+DTSTAMP:20071114T000000Z
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user02 at example.com
+RRULE:FREQ=DAILY
+END:VEVENT
+END:VCALENDAR
+""",
+ """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+METHOD:REPLY
+BEGIN:VEVENT
+UID:12345-67890-1
+DTSTART:20071115T000000Z
+DTSTAMP:20071114T000000Z
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED:mailto:user02 at example.com
+RRULE:FREQ=DAILY
+END:VEVENT
+END:VCALENDAR
+""",
+ """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890-1
+DTSTART:20071114T000000Z
+DTSTAMP:20071114T000000Z
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0:mailto:user02 at example.com
+RRULE:FREQ=DAILY
+END:VEVENT
+END:VCALENDAR
+""",
+ True,
+ ),
+ (
+ "1.3 Simple Reply - recurring with missing master",
+ """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890-1
+RECURRENCE-ID:20071114T000000Z
+DTSTART:20071114T000000Z
+DTSTAMP:20071114T000000Z
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user02 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+ """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+METHOD:REPLY
+BEGIN:VEVENT
+UID:12345-67890-1
+DTSTART:20071115T000000Z
+DTSTAMP:20071114T000000Z
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED:mailto:user02 at example.com
+RRULE:FREQ=DAILY
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890-1
+RECURRENCE-ID:20071114T000000Z
+DTSTART:20071115T000000Z
+DTSTAMP:20071114T000000Z
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED:mailto:user02 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+ """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890-1
+RECURRENCE-ID:20071114T000000Z
+DTSTART:20071114T000000Z
+DTSTAMP:20071114T000000Z
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED;SCHEDULE-STATUS=2.0:mailto:user02 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+ True,
+ ),
+ (
+ "1.4 Simple Reply - recurring with missing master, invalid override",
+ """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+BEGIN:VEVENT
+UID:12345-67890-1
+RECURRENCE-ID:20071114T000000Z
+DTSTART:20071114T000000Z
+DTSTAMP:20071114T000000Z
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=NEEDS-ACTION:mailto:user02 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+ """BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//CALENDARSERVER.ORG//NONSGML Version 1//EN
+METHOD:REPLY
+BEGIN:VEVENT
+UID:12345-67890-1
+DTSTART:20071114T000000Z
+DTSTAMP:20071114T000000Z
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED:mailto:user02 at example.com
+RRULE:FREQ=DAILY
+END:VEVENT
+BEGIN:VEVENT
+UID:12345-67890-1
+RECURRENCE-ID:20071115T000000Z
+DTSTART:20071115T000000Z
+DTSTAMP:20071114T000000Z
+ORGANIZER:mailto:user01 at example.com
+ATTENDEE;PARTSTAT=ACCEPTED:mailto:user02 at example.com
+END:VEVENT
+END:VCALENDAR
+""",
+ None,
+ False,
+ ),
+ )
+
+ for title, calendar_txt, itip_txt, changed_txt, expected in data:
+ calendar = Component.fromString(calendar_txt)
+ itip = Component.fromString(itip_txt)
+ if expected:
+ changed = Component.fromString(changed_txt)
+
+ result, _ignore = iTipProcessing.processReply(itip, calendar)
+ self.assertEqual(result, expected, msg="Result mismatch: %s" % (title,))
+ if expected:
+ self.assertEqual(changed, calendar, msg="Calendar mismatch: %s" % (title,))
+
+
def test_update_attendee_partstat(self):
data = (
@@ -867,9 +1072,9 @@
reply_success, reply_processed = iTipProcessing.processReply(itipmsg, calendar)
# if not description.startswith("#3.1"):
# continue
-# print description
-# print str(calendar)
-# print str(result)
+# print(description)
+# print(str(calendar))
+# print(str(result))
self.assertEqual(
str(calendar).replace("\r", "").replace("\n ", ""),
str(result).replace("\n ", ""),
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/test/test_utils.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/test/test_utils.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/scheduling/test/test_utils.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -97,7 +97,7 @@
}
},
"user02" : {
- "calendar1" : {
+ "calendar2" : {
"2.ics" : (ATTENDEE_ICS, metadata,),
},
"calendar3" : {
@@ -151,8 +151,8 @@
request = FakeRequest(self.rootResource, "PUT", path='/user01/outbox')
for uri in (
"/calendars/__uids__/user01/calendar1/1.ics",
- "/calendars/__uids__/user02/calendar1/2.ics",
- "/calendars/__uids__/user02/calendar2/3.ics",
+ "/calendars/__uids__/user02/calendar2/2.ics",
+ "/calendars/__uids__/user02/calendar3/3.ics",
):
resource = (yield request.locateResource(uri))
self.assertNotEqual(resource, None)
@@ -171,8 +171,8 @@
request = FakeRequest(self.rootResource, "PUT", path='/user01/outbox')
for uri in (
"/calendars/__uids__/user01/calendar1/1.ics",
- "/calendars/__uids__/user02/calendar1/2.ics",
- "/calendars/__uids__/user02/calendar2/3.ics",
+ "/calendars/__uids__/user02/calendar2/2.ics",
+ "/calendars/__uids__/user02/calendar3/3.ics",
):
resource = (yield request.locateResource(uri))
self.assertNotEqual(resource, None)
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/sharing.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/sharing.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/sharing.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -393,7 +393,8 @@
returnValue(result)
# Direct shares use underlying privileges of shared collection
- userprivs = []
+ userprivs = [
+ ]
if access in ("read-only", "read-write",):
userprivs.append(element.Privilege(element.Read()))
userprivs.append(element.Privilege(element.ReadACL()))
@@ -628,7 +629,7 @@
@inlineCallbacks
def _invitationForUID(self, uid):
"""
- Get an invitation for an invitations uid
+ Get an invitation for an invitations uid
"""
invitations = yield self._allInvitations()
for invitation in invitations:
@@ -1228,8 +1229,8 @@
if sharedResource.isCalendarCollection():
shareeHomeResource = yield sharee.calendarHome(request)
- shareeCalenderURL = joinURL(shareeHomeResource.url(), share.name())
- shareeCalender = yield request.locateResource(shareeCalenderURL)
+ sharedAsURL = joinURL(shareeHomeResource.url(), share.name())
+ shareeCalender = yield request.locateResource(sharedAsURL)
shareeCalender.setShare(share)
# For calendars only, per-user displayname and color
@@ -1255,27 +1256,19 @@
elif sharedResource.isAddressBookCollection():
shareeHomeResource = yield sharee.addressBookHome(request)
- shareeAddressBookURL = joinURL(shareeHomeResource.url(), share.ownerUID())
- shareeAddressBook = yield request.locateResource(shareeAddressBookURL)
+ sharedAsURL = joinURL(shareeHomeResource.url(), share.ownerUID())
+ shareeAddressBook = yield request.locateResource(sharedAsURL)
shareeAddressBook.setShare(share)
elif sharedResource.isGroup():
shareeHomeResource = yield sharee.addressBookHome(request)
- shareeGroupURL = joinURL(shareeHomeResource.url(), share.ownerUID(), share.name())
- shareeGroup = yield request.locateResource(shareeGroupURL)
+ sharedAsURL = joinURL(shareeHomeResource.url(), share.ownerUID(), share.name())
+ shareeGroup = yield request.locateResource(sharedAsURL)
shareeGroup.setShare(share)
# Notify client of changes
yield self.notifyChanged()
- #FIXME: shouldn't sharedAsURLbe the same as shareeCollectionURL ?
- if sharedResource.isCalendarCollection():
- sharedAsURL = joinURL(self.url(), share.name())
- elif sharedResource.isAddressBookCollection():
- sharedAsURL = joinURL(self.url(), share.ownerUID())
- elif sharedResource.isGroup():
- sharedAsURL = joinURL(self.url(), share.ownerUID(), share.name())
-
# Return the URL of the shared collection
returnValue(XMLResponse(
code=responsecode.OK,
@@ -1326,7 +1319,7 @@
shared = (yield request.locateResource(shareURL))
displayname = shared.displayName()
- #FIXME: remove if not needed
+ #FIXME: Remove! Probably obsolete
if self.isCalendarCollection():
# For backwards compatibility we need to sync this up with the calendar-free-busy-set on the inbox
principal = (yield self.resourceOwnerPrincipal(request))
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/stdconfig.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/stdconfig.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/stdconfig.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -302,6 +302,10 @@
# the master process, rather than having
# each client make its connections directly.
+ "FailIfUpgradeNeeded" : True, # Set to True to prevent the server or utility tools
+ # tools from running if the database needs a schema
+ # upgrade.
+
#
# Types of service provided
#
@@ -713,6 +717,7 @@
# "accept-if-free" - accept if free, do nothing if busy
# "decline-if-busy" - decline if busy, do nothing if free
# "automatic" - accept if free, decline if busy
+ "FutureFreeBusyDays" : 3 * 365, # How far into the future to check for booking conflicts
}
}
},
@@ -731,14 +736,12 @@
"CoalesceSeconds" : 3,
"Services" : {
- "ApplePushNotifier" : {
- "Service" : "calendarserver.push.applepush.ApplePushNotifierService",
+ "APNS" : {
"Enabled" : False,
"SubscriptionURL" : "apns",
"SubscriptionRefreshIntervalSeconds" : 2 * 24 * 60 * 60, # How often the client should re-register (2 days)
"SubscriptionPurgeIntervalSeconds" : 12 * 60 * 60, # How often a purge is done (12 hours)
"SubscriptionPurgeSeconds" : 14 * 24 * 60 * 60, # How old a subscription must be before it's purged (14 days)
- "DataHost" : "",
"ProviderHost" : "gateway.push.apple.com",
"ProviderPort" : 2195,
"FeedbackHost" : "feedback.push.apple.com",
@@ -762,13 +765,11 @@
"Topic" : "",
},
},
- "AMPNotifier" : {
- "Service" : "calendarserver.push.amppush.AMPPushNotifierService",
+ "AMP" : {
"Enabled" : False,
"Port" : 62311,
"EnableStaggering" : False,
"StaggerSeconds" : 3,
- "DataHost" : "",
},
}
},
@@ -1342,7 +1343,7 @@
if reloading:
return
- for key, service in configDict.Notifications["Services"].iteritems():
+ for _ignore_key, service in configDict.Notifications["Services"].iteritems():
if service["Enabled"]:
configDict.Notifications["Enabled"] = True
break
@@ -1351,14 +1352,7 @@
for key, service in configDict.Notifications["Services"].iteritems():
- if (
- service["Service"] == "calendarserver.push.applepush.ApplePushNotifierService" and
- service["Enabled"]
- ):
- # The default for apple push DataHost is ServerHostName
- if service["DataHost"] == "":
- service["DataHost"] = configDict.ServerHostName
-
+ if (key == "APNS" and service["Enabled"]):
# Retrieve APN topics from certificates if not explicitly set
for protocol, accountName in (
("CalDAV", "apns:com.apple.calendar"),
@@ -1386,18 +1380,9 @@
except KeychainPasswordNotFound:
# The password doesn't exist in the keychain.
log.info("%s APN certificate passphrase not found in keychain" % (protocol,))
-
- if (
- service["Service"] == "calendarserver.push.amppush.AMPPushNotifierService" and
- service["Enabled"]
- ):
- # The default for apple push DataHost is ServerHostName
- if service["DataHost"] == "":
- service["DataHost"] = configDict.ServerHostName
-
def _updateScheduling(configDict, reloading=False):
#
# Scheduling
Modified: CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/test/util.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/test/util.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/twistedcaldav/test/util.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
-
+from __future__ import print_function
from __future__ import with_statement
import os
@@ -340,7 +340,7 @@
if childStructure.has_key("@optional"):
return True
else:
- print "Missing:", childPath
+ print("Missing:", childPath)
return False
if childStructure.has_key("@contents"):
@@ -354,15 +354,15 @@
contents = child.read()
for term in expectedContents:
if term not in contents:
- print "Contents mismatch:", childPath
- print "Expecting match:\n%s\n\nActual:\n%s\n" % (term, contents)
+ print("Contents mismatch:", childPath)
+ print("Expecting match:\n%s\n\nActual:\n%s\n" % (term, contents))
return False
else:
with open(childPath) as child:
contents = child.read()
if contents != childStructure["@contents"]:
- print "Contents mismatch:", childPath
- print "Expected:\n%s\n\nActual:\n%s\n" % (childStructure["@contents"], contents)
+ print("Contents mismatch:", childPath)
+ print("Expected:\n%s\n\nActual:\n%s\n" % (childStructure["@contents"], contents))
return False
else:
@@ -382,8 +382,8 @@
for attr, value in xattrs.iteritems():
if isinstance(value, str):
if xattr.getxattr(childPath, attr) != value:
- print "Xattr mismatch:", childPath, attr
- print (xattr.getxattr(childPath, attr), " != ", value)
+ print("Xattr mismatch:", childPath, attr)
+ print((xattr.getxattr(childPath, attr), " != ", value))
return False
else: # method
if not value(xattr.getxattr(childPath, attr)):
@@ -398,7 +398,7 @@
if actual:
# There are unexpected children
- print "Unexpected:", actual, 'in', parent
+ print("Unexpected:", actual, 'in', parent)
return False
return True
Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/base/datastore/file.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/base/datastore/file.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/base/datastore/file.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,24 +14,25 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+from __future__ import print_function
-
"""
Common utility functions for a file based datastore.
"""
+from zope.interface.declarations import implements
+
+from twisted.python import hashlib
+
from twext.python.log import LoggingMixIn
from twext.enterprise.ienterprise import AlreadyFinishedError
+from twext.web2.dav.resource import TwistedGETContentMD5
from txdav.idav import IDataStoreObject
from txdav.base.propertystore.base import PropertyName
+from txdav.xml.element import GETContentType
-from txdav.xml.rfc2518 import GETContentType
-from twext.web2.dav.resource import TwistedGETContentMD5
-from twisted.python import hashlib
-from zope.interface.declarations import implements
-
def isValidName(name):
"""
Determine if the given string is a valid name. i.e. does it conflict with
@@ -102,12 +103,12 @@
def __del__(self):
if not self.done and self.info:
- print '**** UNCOMMITTED TRANSACTION (%s) BEING GARBAGE COLLECTED ****' % (
+ print("**** UNCOMMITTED TRANSACTION (%s) BEING GARBAGE COLLECTED ****") % (
self.name,
)
for info in self.info:
- print ' ', info
- print '---- END OF OPERATIONS'
+ print(" "), info
+ print("---- END OF OPERATIONS")
Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/current-oracle-dialect.sql
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/current-oracle-dialect.sql 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/current-oracle-dialect.sql 2013-03-07 22:42:21 UTC (rev 10867)
@@ -95,7 +95,6 @@
"ATTACHMENTS_MODE" integer default 0 not null,
"DROPBOX_ID" nvarchar2(255),
"ORGANIZER" nvarchar2(255),
- "ORGANIZER_OBJECT" integer references CALENDAR_OBJECT,
"RECURRANCE_MIN" date,
"RECURRANCE_MAX" date,
"ACCESS" integer default 0 not null,
@@ -306,7 +305,7 @@
"VALUE" nvarchar2(255)
);
-insert into CALENDARSERVER (NAME, VALUE) values ('VERSION', '16');
+insert into CALENDARSERVER (NAME, VALUE) values ('VERSION', '17');
insert into CALENDARSERVER (NAME, VALUE) values ('CALENDAR-DATAVERSION', '3');
insert into CALENDARSERVER (NAME, VALUE) values ('ADDRESSBOOK-DATAVERSION', '1');
create index NOTIFICATION_NOTIFICA_f891f5f9 on NOTIFICATION (
@@ -327,8 +326,8 @@
RECURRANCE_MAX
);
-create index CALENDAR_OBJECT_ORGAN_7ce24750 on CALENDAR_OBJECT (
- ORGANIZER_OBJECT
+create index CALENDAR_OBJECT_ICALE_82e731d5 on CALENDAR_OBJECT (
+ ICALENDAR_UID
);
create index CALENDAR_OBJECT_DROPB_de041d80 on CALENDAR_OBJECT (
Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/current.sql
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/current.sql 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/current.sql 2013-03-07 22:42:21 UTC (rev 10867)
@@ -176,7 +176,6 @@
ATTACHMENTS_MODE integer default 0 not null, -- enum CALENDAR_OBJECT_ATTACHMENTS_MODE
DROPBOX_ID varchar(255),
ORGANIZER varchar(255),
- ORGANIZER_OBJECT integer references CALENDAR_OBJECT,
RECURRANCE_MIN date, -- minimum date that recurrences have been expanded to.
RECURRANCE_MAX date, -- maximum date that recurrences have been expanded to.
ACCESS integer default 0 not null,
@@ -203,8 +202,8 @@
create index CALENDAR_OBJECT_CALENDAR_RESOURCE_ID_RECURRANCE_MAX on
CALENDAR_OBJECT(CALENDAR_RESOURCE_ID, RECURRANCE_MAX);
-create index CALENDAR_OBJECT_ORGANIZER_OBJECT on
- CALENDAR_OBJECT(ORGANIZER_OBJECT);
+create index CALENDAR_OBJECT_ICALENDAR_UID on
+ CALENDAR_OBJECT(ICALENDAR_UID);
create index CALENDAR_OBJECT_DROPBOX_ID on
CALENDAR_OBJECT(DROPBOX_ID);
@@ -342,10 +341,10 @@
----------------------
create table ADDRESSBOOK_HOME (
- RESOURCE_ID integer primary key default nextval('RESOURCE_ID_SEQ'), -- implicit index
- HOME_RESOURCE_ID integer default nextval('RESOURCE_ID_SEQ') not null, -- implicit index
- OWNER_UID varchar(255) not null unique, -- implicit index
- DATAVERSION integer default 0 not null
+ RESOURCE_ID integer primary key default nextval('RESOURCE_ID_SEQ'), -- implicit index
+ HOME_RESOURCE_ID integer default nextval('RESOURCE_ID_SEQ') not null, -- implicit index
+ OWNER_UID varchar(255) not null unique, -- implicit index
+ DATAVERSION integer default 0 not null
);
@@ -393,7 +392,7 @@
RESOURCE_NAME varchar(255) not null,
VCARD_TEXT text not null,
VCARD_UID varchar(255) not null,
- KIND integer not null, -- enum OBJECT_KIND
+ KIND integer not null, -- enum OBJECT_KIND
MD5 char(32) not null,
CREATED timestamp default timezone('UTC', CURRENT_TIMESTAMP),
MODIFIED timestamp default timezone('UTC', CURRENT_TIMESTAMP),
@@ -623,6 +622,6 @@
VALUE varchar(255)
);
-insert into CALENDARSERVER values ('VERSION', '16');
+insert into CALENDARSERVER values ('VERSION', '17');
insert into CALENDARSERVER values ('CALENDAR-DATAVERSION', '3');
insert into CALENDARSERVER values ('ADDRESSBOOK-DATAVERSION', '1');
Copied: CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/old/oracle-dialect/v16.sql (from rev 10865, CalendarServer/trunk/txdav/common/datastore/sql_schema/old/oracle-dialect/v16.sql)
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/old/oracle-dialect/v16.sql (rev 0)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/old/oracle-dialect/v16.sql 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,400 @@
+create sequence RESOURCE_ID_SEQ;
+create sequence INSTANCE_ID_SEQ;
+create sequence ATTACHMENT_ID_SEQ;
+create sequence REVISION_SEQ;
+create sequence WORKITEM_SEQ;
+create table NODE_INFO (
+ "HOSTNAME" nvarchar2(255),
+ "PID" integer not null,
+ "PORT" integer not null,
+ "TIME" timestamp default CURRENT_TIMESTAMP at time zone 'UTC' not null,
+ primary key("HOSTNAME", "PORT")
+);
+
+create table NAMED_LOCK (
+ "LOCK_NAME" nvarchar2(255) primary key
+);
+
+create table CALENDAR_HOME (
+ "RESOURCE_ID" integer primary key,
+ "OWNER_UID" nvarchar2(255) unique,
+ "DATAVERSION" integer default 0 not null
+);
+
+create table CALENDAR_HOME_METADATA (
+ "RESOURCE_ID" integer primary key references CALENDAR_HOME on delete cascade,
+ "QUOTA_USED_BYTES" integer default 0 not null,
+ "CREATED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
+ "MODIFIED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC'
+);
+
+create table CALENDAR (
+ "RESOURCE_ID" integer primary key
+);
+
+create table CALENDAR_METADATA (
+ "RESOURCE_ID" integer primary key references CALENDAR on delete cascade,
+ "SUPPORTED_COMPONENTS" nvarchar2(255) default null,
+ "CREATED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
+ "MODIFIED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC'
+);
+
+create table NOTIFICATION_HOME (
+ "RESOURCE_ID" integer primary key,
+ "OWNER_UID" nvarchar2(255) unique
+);
+
+create table NOTIFICATION (
+ "RESOURCE_ID" integer primary key,
+ "NOTIFICATION_HOME_RESOURCE_ID" integer not null references NOTIFICATION_HOME,
+ "NOTIFICATION_UID" nvarchar2(255),
+ "XML_TYPE" nvarchar2(255),
+ "XML_DATA" nclob,
+ "MD5" nchar(32),
+ "CREATED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
+ "MODIFIED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
+ unique("NOTIFICATION_UID", "NOTIFICATION_HOME_RESOURCE_ID")
+);
+
+create table CALENDAR_BIND (
+ "CALENDAR_HOME_RESOURCE_ID" integer not null references CALENDAR_HOME,
+ "CALENDAR_RESOURCE_ID" integer not null references CALENDAR on delete cascade,
+ "CALENDAR_RESOURCE_NAME" nvarchar2(255),
+ "BIND_MODE" integer not null,
+ "BIND_STATUS" integer not null,
+ "MESSAGE" nclob,
+ primary key("CALENDAR_HOME_RESOURCE_ID", "CALENDAR_RESOURCE_ID"),
+ unique("CALENDAR_HOME_RESOURCE_ID", "CALENDAR_RESOURCE_NAME")
+);
+
+create table CALENDAR_BIND_MODE (
+ "ID" integer primary key,
+ "DESCRIPTION" nvarchar2(16) unique
+);
+
+insert into CALENDAR_BIND_MODE (DESCRIPTION, ID) values ('own', 0);
+insert into CALENDAR_BIND_MODE (DESCRIPTION, ID) values ('read', 1);
+insert into CALENDAR_BIND_MODE (DESCRIPTION, ID) values ('write', 2);
+insert into CALENDAR_BIND_MODE (DESCRIPTION, ID) values ('direct', 3);
+create table CALENDAR_BIND_STATUS (
+ "ID" integer primary key,
+ "DESCRIPTION" nvarchar2(16) unique
+);
+
+insert into CALENDAR_BIND_STATUS (DESCRIPTION, ID) values ('invited', 0);
+insert into CALENDAR_BIND_STATUS (DESCRIPTION, ID) values ('accepted', 1);
+insert into CALENDAR_BIND_STATUS (DESCRIPTION, ID) values ('declined', 2);
+insert into CALENDAR_BIND_STATUS (DESCRIPTION, ID) values ('invalid', 3);
+create table CALENDAR_OBJECT (
+ "RESOURCE_ID" integer primary key,
+ "CALENDAR_RESOURCE_ID" integer not null references CALENDAR on delete cascade,
+ "RESOURCE_NAME" nvarchar2(255),
+ "ICALENDAR_TEXT" nclob,
+ "ICALENDAR_UID" nvarchar2(255),
+ "ICALENDAR_TYPE" nvarchar2(255),
+ "ATTACHMENTS_MODE" integer default 0 not null,
+ "DROPBOX_ID" nvarchar2(255),
+ "ORGANIZER" nvarchar2(255),
+ "ORGANIZER_OBJECT" integer references CALENDAR_OBJECT,
+ "RECURRANCE_MIN" date,
+ "RECURRANCE_MAX" date,
+ "ACCESS" integer default 0 not null,
+ "SCHEDULE_OBJECT" integer default 0,
+ "SCHEDULE_TAG" nvarchar2(36) default null,
+ "SCHEDULE_ETAGS" nclob default null,
+ "PRIVATE_COMMENTS" integer default 0 not null,
+ "MD5" nchar(32),
+ "CREATED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
+ "MODIFIED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
+ unique("CALENDAR_RESOURCE_ID", "RESOURCE_NAME")
+);
+
+create table CALENDAR_OBJECT_ATTACHMENTS_MO (
+ "ID" integer primary key,
+ "DESCRIPTION" nvarchar2(16) unique
+);
+
+insert into CALENDAR_OBJECT_ATTACHMENTS_MO (DESCRIPTION, ID) values ('none', 0);
+insert into CALENDAR_OBJECT_ATTACHMENTS_MO (DESCRIPTION, ID) values ('read', 1);
+insert into CALENDAR_OBJECT_ATTACHMENTS_MO (DESCRIPTION, ID) values ('write', 2);
+create table CALENDAR_ACCESS_TYPE (
+ "ID" integer primary key,
+ "DESCRIPTION" nvarchar2(32) unique
+);
+
+insert into CALENDAR_ACCESS_TYPE (DESCRIPTION, ID) values ('', 0);
+insert into CALENDAR_ACCESS_TYPE (DESCRIPTION, ID) values ('public', 1);
+insert into CALENDAR_ACCESS_TYPE (DESCRIPTION, ID) values ('private', 2);
+insert into CALENDAR_ACCESS_TYPE (DESCRIPTION, ID) values ('confidential', 3);
+insert into CALENDAR_ACCESS_TYPE (DESCRIPTION, ID) values ('restricted', 4);
+create table TIME_RANGE (
+ "INSTANCE_ID" integer primary key,
+ "CALENDAR_RESOURCE_ID" integer not null references CALENDAR on delete cascade,
+ "CALENDAR_OBJECT_RESOURCE_ID" integer not null references CALENDAR_OBJECT on delete cascade,
+ "FLOATING" integer not null,
+ "START_DATE" timestamp not null,
+ "END_DATE" timestamp not null,
+ "FBTYPE" integer not null,
+ "TRANSPARENT" integer not null
+);
+
+create table FREE_BUSY_TYPE (
+ "ID" integer primary key,
+ "DESCRIPTION" nvarchar2(16) unique
+);
+
+insert into FREE_BUSY_TYPE (DESCRIPTION, ID) values ('unknown', 0);
+insert into FREE_BUSY_TYPE (DESCRIPTION, ID) values ('free', 1);
+insert into FREE_BUSY_TYPE (DESCRIPTION, ID) values ('busy', 2);
+insert into FREE_BUSY_TYPE (DESCRIPTION, ID) values ('busy-unavailable', 3);
+insert into FREE_BUSY_TYPE (DESCRIPTION, ID) values ('busy-tentative', 4);
+create table TRANSPARENCY (
+ "TIME_RANGE_INSTANCE_ID" integer not null references TIME_RANGE on delete cascade,
+ "USER_ID" nvarchar2(255),
+ "TRANSPARENT" integer not null
+);
+
+create table ATTACHMENT (
+ "ATTACHMENT_ID" integer primary key,
+ "CALENDAR_HOME_RESOURCE_ID" integer not null references CALENDAR_HOME,
+ "DROPBOX_ID" nvarchar2(255),
+ "CONTENT_TYPE" nvarchar2(255),
+ "SIZE" integer not null,
+ "MD5" nchar(32),
+ "CREATED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
+ "MODIFIED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
+ "PATH" nvarchar2(1024)
+);
+
+create table ATTACHMENT_CALENDAR_OBJECT (
+ "ATTACHMENT_ID" integer not null references ATTACHMENT on delete cascade,
+ "MANAGED_ID" nvarchar2(255),
+ "CALENDAR_OBJECT_RESOURCE_ID" integer not null references CALENDAR_OBJECT on delete cascade,
+ primary key("ATTACHMENT_ID", "CALENDAR_OBJECT_RESOURCE_ID"),
+ unique("MANAGED_ID", "CALENDAR_OBJECT_RESOURCE_ID")
+);
+
+create table RESOURCE_PROPERTY (
+ "RESOURCE_ID" integer not null,
+ "NAME" nvarchar2(255),
+ "VALUE" nclob,
+ "VIEWER_UID" nvarchar2(255),
+ primary key("RESOURCE_ID", "NAME", "VIEWER_UID")
+);
+
+create table ADDRESSBOOK_HOME (
+ "RESOURCE_ID" integer primary key,
+ "OWNER_UID" nvarchar2(255) unique,
+ "DATAVERSION" integer default 0 not null
+);
+
+create table ADDRESSBOOK_HOME_METADATA (
+ "RESOURCE_ID" integer primary key references ADDRESSBOOK_HOME on delete cascade,
+ "QUOTA_USED_BYTES" integer default 0 not null,
+ "CREATED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
+ "MODIFIED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC'
+);
+
+create table ADDRESSBOOK (
+ "RESOURCE_ID" integer primary key
+);
+
+create table ADDRESSBOOK_METADATA (
+ "RESOURCE_ID" integer primary key references ADDRESSBOOK on delete cascade,
+ "CREATED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
+ "MODIFIED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC'
+);
+
+create table ADDRESSBOOK_BIND (
+ "ADDRESSBOOK_HOME_RESOURCE_ID" integer not null references ADDRESSBOOK_HOME,
+ "ADDRESSBOOK_RESOURCE_ID" integer not null references ADDRESSBOOK on delete cascade,
+ "ADDRESSBOOK_RESOURCE_NAME" nvarchar2(255),
+ "BIND_MODE" integer not null,
+ "BIND_STATUS" integer not null,
+ "MESSAGE" nclob,
+ primary key("ADDRESSBOOK_HOME_RESOURCE_ID", "ADDRESSBOOK_RESOURCE_ID"),
+ unique("ADDRESSBOOK_HOME_RESOURCE_ID", "ADDRESSBOOK_RESOURCE_NAME")
+);
+
+create table ADDRESSBOOK_OBJECT (
+ "RESOURCE_ID" integer primary key,
+ "ADDRESSBOOK_RESOURCE_ID" integer not null references ADDRESSBOOK on delete cascade,
+ "RESOURCE_NAME" nvarchar2(255),
+ "VCARD_TEXT" nclob,
+ "VCARD_UID" nvarchar2(255),
+ "MD5" nchar(32),
+ "CREATED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
+ "MODIFIED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
+ unique("ADDRESSBOOK_RESOURCE_ID", "RESOURCE_NAME"),
+ unique("ADDRESSBOOK_RESOURCE_ID", "VCARD_UID")
+);
+
+create table CALENDAR_OBJECT_REVISIONS (
+ "CALENDAR_HOME_RESOURCE_ID" integer not null references CALENDAR_HOME,
+ "CALENDAR_RESOURCE_ID" integer references CALENDAR,
+ "CALENDAR_NAME" nvarchar2(255) default null,
+ "RESOURCE_NAME" nvarchar2(255),
+ "REVISION" integer not null,
+ "DELETED" integer not null
+);
+
+create table ADDRESSBOOK_OBJECT_REVISIONS (
+ "ADDRESSBOOK_HOME_RESOURCE_ID" integer not null references ADDRESSBOOK_HOME,
+ "ADDRESSBOOK_RESOURCE_ID" integer references ADDRESSBOOK,
+ "ADDRESSBOOK_NAME" nvarchar2(255) default null,
+ "RESOURCE_NAME" nvarchar2(255),
+ "REVISION" integer not null,
+ "DELETED" integer not null
+);
+
+create table NOTIFICATION_OBJECT_REVISIONS (
+ "NOTIFICATION_HOME_RESOURCE_ID" integer not null references NOTIFICATION_HOME on delete cascade,
+ "RESOURCE_NAME" nvarchar2(255),
+ "REVISION" integer not null,
+ "DELETED" integer not null,
+ unique("NOTIFICATION_HOME_RESOURCE_ID", "RESOURCE_NAME")
+);
+
+create table APN_SUBSCRIPTIONS (
+ "TOKEN" nvarchar2(255),
+ "RESOURCE_KEY" nvarchar2(255),
+ "MODIFIED" integer not null,
+ "SUBSCRIBER_GUID" nvarchar2(255),
+ "USER_AGENT" nvarchar2(255) default null,
+ "IP_ADDR" nvarchar2(255) default null,
+ primary key("TOKEN", "RESOURCE_KEY")
+);
+
+create table IMIP_TOKENS (
+ "TOKEN" nvarchar2(255),
+ "ORGANIZER" nvarchar2(255),
+ "ATTENDEE" nvarchar2(255),
+ "ICALUID" nvarchar2(255),
+ "ACCESSED" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
+ primary key("ORGANIZER", "ATTENDEE", "ICALUID")
+);
+
+create table IMIP_INVITATION_WORK (
+ "WORK_ID" integer primary key not null,
+ "NOT_BEFORE" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
+ "FROM_ADDR" nvarchar2(255),
+ "TO_ADDR" nvarchar2(255),
+ "ICALENDAR_TEXT" nclob
+);
+
+create table IMIP_POLLING_WORK (
+ "WORK_ID" integer primary key not null,
+ "NOT_BEFORE" timestamp default CURRENT_TIMESTAMP at time zone 'UTC'
+);
+
+create table IMIP_REPLY_WORK (
+ "WORK_ID" integer primary key not null,
+ "NOT_BEFORE" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
+ "ORGANIZER" nvarchar2(255),
+ "ATTENDEE" nvarchar2(255),
+ "ICALENDAR_TEXT" nclob
+);
+
+create table PUSH_NOTIFICATION_WORK (
+ "WORK_ID" integer primary key not null,
+ "NOT_BEFORE" timestamp default CURRENT_TIMESTAMP at time zone 'UTC',
+ "PUSH_ID" nvarchar2(255)
+);
+
+create table CALENDARSERVER (
+ "NAME" nvarchar2(255) primary key,
+ "VALUE" nvarchar2(255)
+);
+
+insert into CALENDARSERVER (NAME, VALUE) values ('VERSION', '16');
+insert into CALENDARSERVER (NAME, VALUE) values ('CALENDAR-DATAVERSION', '3');
+insert into CALENDARSERVER (NAME, VALUE) values ('ADDRESSBOOK-DATAVERSION', '1');
+create index NOTIFICATION_NOTIFICA_f891f5f9 on NOTIFICATION (
+ NOTIFICATION_HOME_RESOURCE_ID
+);
+
+create index CALENDAR_BIND_RESOURC_e57964d4 on CALENDAR_BIND (
+ CALENDAR_RESOURCE_ID
+);
+
+create index CALENDAR_OBJECT_CALEN_a9a453a9 on CALENDAR_OBJECT (
+ CALENDAR_RESOURCE_ID,
+ ICALENDAR_UID
+);
+
+create index CALENDAR_OBJECT_CALEN_96e83b73 on CALENDAR_OBJECT (
+ CALENDAR_RESOURCE_ID,
+ RECURRANCE_MAX
+);
+
+create index CALENDAR_OBJECT_ORGAN_7ce24750 on CALENDAR_OBJECT (
+ ORGANIZER_OBJECT
+);
+
+create index CALENDAR_OBJECT_DROPB_de041d80 on CALENDAR_OBJECT (
+ DROPBOX_ID
+);
+
+create index TIME_RANGE_CALENDAR_R_beb6e7eb on TIME_RANGE (
+ CALENDAR_RESOURCE_ID
+);
+
+create index TIME_RANGE_CALENDAR_O_acf37bd1 on TIME_RANGE (
+ CALENDAR_OBJECT_RESOURCE_ID
+);
+
+create index TRANSPARENCY_TIME_RAN_5f34467f on TRANSPARENCY (
+ TIME_RANGE_INSTANCE_ID
+);
+
+create index ATTACHMENT_CALENDAR_H_0078845c on ATTACHMENT (
+ CALENDAR_HOME_RESOURCE_ID
+);
+
+create index ADDRESSBOOK_BIND_RESO_205aa75c on ADDRESSBOOK_BIND (
+ ADDRESSBOOK_RESOURCE_ID
+);
+
+create index CALENDAR_OBJECT_REVIS_3a3956c4 on CALENDAR_OBJECT_REVISIONS (
+ CALENDAR_HOME_RESOURCE_ID,
+ CALENDAR_RESOURCE_ID
+);
+
+create index CALENDAR_OBJECT_REVIS_2643d556 on CALENDAR_OBJECT_REVISIONS (
+ CALENDAR_RESOURCE_ID,
+ RESOURCE_NAME
+);
+
+create index CALENDAR_OBJECT_REVIS_265c8acf on CALENDAR_OBJECT_REVISIONS (
+ CALENDAR_RESOURCE_ID,
+ REVISION
+);
+
+create index ADDRESSBOOK_OBJECT_RE_f460d62d on ADDRESSBOOK_OBJECT_REVISIONS (
+ ADDRESSBOOK_HOME_RESOURCE_ID,
+ ADDRESSBOOK_RESOURCE_ID
+);
+
+create index ADDRESSBOOK_OBJECT_RE_9a848f39 on ADDRESSBOOK_OBJECT_REVISIONS (
+ ADDRESSBOOK_RESOURCE_ID,
+ RESOURCE_NAME
+);
+
+create index ADDRESSBOOK_OBJECT_RE_cb101e6b on ADDRESSBOOK_OBJECT_REVISIONS (
+ ADDRESSBOOK_RESOURCE_ID,
+ REVISION
+);
+
+create index NOTIFICATION_OBJECT_R_036a9cee on NOTIFICATION_OBJECT_REVISIONS (
+ NOTIFICATION_HOME_RESOURCE_ID,
+ REVISION
+);
+
+create index APN_SUBSCRIPTIONS_RES_9610d78e on APN_SUBSCRIPTIONS (
+ RESOURCE_KEY
+);
+
+create index IMIP_TOKENS_TOKEN_e94b918f on IMIP_TOKENS (
+ TOKEN
+);
+
Copied: CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/old/postgres-dialect/v16.sql (from rev 10865, CalendarServer/trunk/txdav/common/datastore/sql_schema/old/postgres-dialect/v16.sql)
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/old/postgres-dialect/v16.sql (rev 0)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/old/postgres-dialect/v16.sql 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,573 @@
+-- -*- test-case-name: txdav.caldav.datastore.test.test_sql,txdav.carddav.datastore.test.test_sql -*-
+
+----
+-- Copyright (c) 2010-2013 Apple Inc. All rights reserved.
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+----
+
+-----------------
+-- Resource ID --
+-----------------
+
+create sequence RESOURCE_ID_SEQ;
+
+-------------------------
+-- Cluster Bookkeeping --
+-------------------------
+
+-- Information about a process connected to this database.
+
+-- Note that this must match the node info schema in twext.enterprise.queue.
+create table NODE_INFO (
+ HOSTNAME varchar(255) not null,
+ PID integer not null,
+ PORT integer not null,
+ TIME timestamp not null default timezone('UTC', CURRENT_TIMESTAMP),
+
+ primary key (HOSTNAME, PORT)
+);
+
+-- Unique named locks. This table should always be empty, but rows are
+-- temporarily created in order to prevent undesirable concurrency.
+create table NAMED_LOCK (
+ LOCK_NAME varchar(255) primary key
+);
+
+
+-------------------
+-- Calendar Home --
+-------------------
+
+create table CALENDAR_HOME (
+ RESOURCE_ID integer primary key default nextval('RESOURCE_ID_SEQ'), -- implicit index
+ OWNER_UID varchar(255) not null unique, -- implicit index
+ DATAVERSION integer default 0 not null
+);
+
+----------------------------
+-- Calendar Home Metadata --
+----------------------------
+
+create table CALENDAR_HOME_METADATA (
+ RESOURCE_ID integer primary key references CALENDAR_HOME on delete cascade, -- implicit index
+ QUOTA_USED_BYTES integer default 0 not null,
+ CREATED timestamp default timezone('UTC', CURRENT_TIMESTAMP),
+ MODIFIED timestamp default timezone('UTC', CURRENT_TIMESTAMP)
+);
+
+--------------
+-- Calendar --
+--------------
+
+create table CALENDAR (
+ RESOURCE_ID integer primary key default nextval('RESOURCE_ID_SEQ') -- implicit index
+);
+
+
+-----------------------
+-- Calendar Metadata --
+-----------------------
+
+create table CALENDAR_METADATA (
+ RESOURCE_ID integer primary key references CALENDAR on delete cascade, -- implicit index
+ SUPPORTED_COMPONENTS varchar(255) default null,
+ CREATED timestamp default timezone('UTC', CURRENT_TIMESTAMP),
+ MODIFIED timestamp default timezone('UTC', CURRENT_TIMESTAMP)
+);
+
+
+---------------------------
+-- Sharing Notifications --
+---------------------------
+
+create table NOTIFICATION_HOME (
+ RESOURCE_ID integer primary key default nextval('RESOURCE_ID_SEQ'), -- implicit index
+ OWNER_UID varchar(255) not null unique -- implicit index
+);
+
+create table NOTIFICATION (
+ RESOURCE_ID integer primary key default nextval('RESOURCE_ID_SEQ'), -- implicit index
+ NOTIFICATION_HOME_RESOURCE_ID integer not null references NOTIFICATION_HOME,
+ NOTIFICATION_UID varchar(255) not null,
+ XML_TYPE varchar(255) not null,
+ XML_DATA text not null,
+ MD5 char(32) not null,
+ CREATED timestamp default timezone('UTC', CURRENT_TIMESTAMP),
+ MODIFIED timestamp default timezone('UTC', CURRENT_TIMESTAMP),
+
+ unique(NOTIFICATION_UID, NOTIFICATION_HOME_RESOURCE_ID) -- implicit index
+);
+
+create index NOTIFICATION_NOTIFICATION_HOME_RESOURCE_ID on
+ NOTIFICATION(NOTIFICATION_HOME_RESOURCE_ID);
+
+-------------------
+-- Calendar Bind --
+-------------------
+
+-- Joins CALENDAR_HOME and CALENDAR
+
+create table CALENDAR_BIND (
+ CALENDAR_HOME_RESOURCE_ID integer not null references CALENDAR_HOME,
+ CALENDAR_RESOURCE_ID integer not null references CALENDAR on delete cascade,
+ CALENDAR_RESOURCE_NAME varchar(255) not null,
+ BIND_MODE integer not null, -- enum CALENDAR_BIND_MODE
+ BIND_STATUS integer not null, -- enum CALENDAR_BIND_STATUS
+ MESSAGE text,
+
+ primary key(CALENDAR_HOME_RESOURCE_ID, CALENDAR_RESOURCE_ID), -- implicit index
+ unique(CALENDAR_HOME_RESOURCE_ID, CALENDAR_RESOURCE_NAME) -- implicit index
+);
+
+create index CALENDAR_BIND_RESOURCE_ID on CALENDAR_BIND(CALENDAR_RESOURCE_ID);
+
+-- Enumeration of calendar bind modes
+
+create table CALENDAR_BIND_MODE (
+ ID integer primary key,
+ DESCRIPTION varchar(16) not null unique
+);
+
+insert into CALENDAR_BIND_MODE values (0, 'own' );
+insert into CALENDAR_BIND_MODE values (1, 'read' );
+insert into CALENDAR_BIND_MODE values (2, 'write');
+insert into CALENDAR_BIND_MODE values (3, 'direct');
+
+-- Enumeration of statuses
+
+create table CALENDAR_BIND_STATUS (
+ ID integer primary key,
+ DESCRIPTION varchar(16) not null unique
+);
+
+insert into CALENDAR_BIND_STATUS values (0, 'invited' );
+insert into CALENDAR_BIND_STATUS values (1, 'accepted');
+insert into CALENDAR_BIND_STATUS values (2, 'declined');
+insert into CALENDAR_BIND_STATUS values (3, 'invalid');
+
+
+---------------------
+-- Calendar Object --
+---------------------
+
+create table CALENDAR_OBJECT (
+ RESOURCE_ID integer primary key default nextval('RESOURCE_ID_SEQ'), -- implicit index
+ CALENDAR_RESOURCE_ID integer not null references CALENDAR on delete cascade,
+ RESOURCE_NAME varchar(255) not null,
+ ICALENDAR_TEXT text not null,
+ ICALENDAR_UID varchar(255) not null,
+ ICALENDAR_TYPE varchar(255) not null,
+ ATTACHMENTS_MODE integer default 0 not null, -- enum CALENDAR_OBJECT_ATTACHMENTS_MODE
+ DROPBOX_ID varchar(255),
+ ORGANIZER varchar(255),
+ ORGANIZER_OBJECT integer references CALENDAR_OBJECT,
+ RECURRANCE_MIN date, -- minimum date that recurrences have been expanded to.
+ RECURRANCE_MAX date, -- maximum date that recurrences have been expanded to.
+ ACCESS integer default 0 not null,
+ SCHEDULE_OBJECT boolean default false,
+ SCHEDULE_TAG varchar(36) default null,
+ SCHEDULE_ETAGS text default null,
+ PRIVATE_COMMENTS boolean default false not null,
+ MD5 char(32) not null,
+ CREATED timestamp default timezone('UTC', CURRENT_TIMESTAMP),
+ MODIFIED timestamp default timezone('UTC', CURRENT_TIMESTAMP),
+
+ unique (CALENDAR_RESOURCE_ID, RESOURCE_NAME) -- implicit index
+
+ -- since the 'inbox' is a 'calendar resource' for the purpose of storing
+ -- calendar objects, this constraint has to be selectively enforced by the
+ -- application layer.
+
+ -- unique(CALENDAR_RESOURCE_ID, ICALENDAR_UID)
+);
+
+create index CALENDAR_OBJECT_CALENDAR_RESOURCE_ID_AND_ICALENDAR_UID on
+ CALENDAR_OBJECT(CALENDAR_RESOURCE_ID, ICALENDAR_UID);
+
+create index CALENDAR_OBJECT_CALENDAR_RESOURCE_ID_RECURRANCE_MAX on
+ CALENDAR_OBJECT(CALENDAR_RESOURCE_ID, RECURRANCE_MAX);
+
+create index CALENDAR_OBJECT_ORGANIZER_OBJECT on
+ CALENDAR_OBJECT(ORGANIZER_OBJECT);
+
+create index CALENDAR_OBJECT_DROPBOX_ID on
+ CALENDAR_OBJECT(DROPBOX_ID);
+
+-- Enumeration of attachment modes
+
+create table CALENDAR_OBJECT_ATTACHMENTS_MODE (
+ ID integer primary key,
+ DESCRIPTION varchar(16) not null unique
+);
+
+insert into CALENDAR_OBJECT_ATTACHMENTS_MODE values (0, 'none' );
+insert into CALENDAR_OBJECT_ATTACHMENTS_MODE values (1, 'read' );
+insert into CALENDAR_OBJECT_ATTACHMENTS_MODE values (2, 'write');
+
+
+-- Enumeration of calendar access types
+
+create table CALENDAR_ACCESS_TYPE (
+ ID integer primary key,
+ DESCRIPTION varchar(32) not null unique
+);
+
+insert into CALENDAR_ACCESS_TYPE values (0, '' );
+insert into CALENDAR_ACCESS_TYPE values (1, 'public' );
+insert into CALENDAR_ACCESS_TYPE values (2, 'private' );
+insert into CALENDAR_ACCESS_TYPE values (3, 'confidential' );
+insert into CALENDAR_ACCESS_TYPE values (4, 'restricted' );
+
+-----------------
+-- Instance ID --
+-----------------
+
+create sequence INSTANCE_ID_SEQ;
+
+
+----------------
+-- Time Range --
+----------------
+
+create table TIME_RANGE (
+ INSTANCE_ID integer primary key default nextval('INSTANCE_ID_SEQ'), -- implicit index
+ CALENDAR_RESOURCE_ID integer not null references CALENDAR on delete cascade,
+ CALENDAR_OBJECT_RESOURCE_ID integer not null references CALENDAR_OBJECT on delete cascade,
+ FLOATING boolean not null,
+ START_DATE timestamp not null,
+ END_DATE timestamp not null,
+ FBTYPE integer not null,
+ TRANSPARENT boolean not null
+);
+
+create index TIME_RANGE_CALENDAR_RESOURCE_ID on
+ TIME_RANGE(CALENDAR_RESOURCE_ID);
+create index TIME_RANGE_CALENDAR_OBJECT_RESOURCE_ID on
+ TIME_RANGE(CALENDAR_OBJECT_RESOURCE_ID);
+
+
+-- Enumeration of free/busy types
+
+create table FREE_BUSY_TYPE (
+ ID integer primary key,
+ DESCRIPTION varchar(16) not null unique
+);
+
+insert into FREE_BUSY_TYPE values (0, 'unknown' );
+insert into FREE_BUSY_TYPE values (1, 'free' );
+insert into FREE_BUSY_TYPE values (2, 'busy' );
+insert into FREE_BUSY_TYPE values (3, 'busy-unavailable');
+insert into FREE_BUSY_TYPE values (4, 'busy-tentative' );
+
+
+------------------
+-- Transparency --
+------------------
+
+create table TRANSPARENCY (
+ TIME_RANGE_INSTANCE_ID integer not null references TIME_RANGE on delete cascade,
+ USER_ID varchar(255) not null,
+ TRANSPARENT boolean not null
+);
+
+create index TRANSPARENCY_TIME_RANGE_INSTANCE_ID on
+ TRANSPARENCY(TIME_RANGE_INSTANCE_ID);
+
+
+----------------
+-- Attachment --
+----------------
+
+create sequence ATTACHMENT_ID_SEQ;
+
+create table ATTACHMENT (
+ ATTACHMENT_ID integer primary key default nextval('ATTACHMENT_ID_SEQ'), -- implicit index
+ CALENDAR_HOME_RESOURCE_ID integer not null references CALENDAR_HOME,
+ DROPBOX_ID varchar(255),
+ CONTENT_TYPE varchar(255) not null,
+ SIZE integer not null,
+ MD5 char(32) not null,
+ CREATED timestamp default timezone('UTC', CURRENT_TIMESTAMP),
+ MODIFIED timestamp default timezone('UTC', CURRENT_TIMESTAMP),
+ PATH varchar(1024) not null
+);
+
+create index ATTACHMENT_CALENDAR_HOME_RESOURCE_ID on
+ ATTACHMENT(CALENDAR_HOME_RESOURCE_ID);
+
+-- Many-to-many relationship between attachments and calendar objects
+create table ATTACHMENT_CALENDAR_OBJECT (
+ ATTACHMENT_ID integer not null references ATTACHMENT on delete cascade,
+ MANAGED_ID varchar(255) not null,
+ CALENDAR_OBJECT_RESOURCE_ID integer not null references CALENDAR_OBJECT on delete cascade,
+
+ primary key (ATTACHMENT_ID, CALENDAR_OBJECT_RESOURCE_ID), -- implicit index
+ unique (MANAGED_ID, CALENDAR_OBJECT_RESOURCE_ID) --implicit index
+);
+
+
+-----------------------
+-- Resource Property --
+-----------------------
+
+create table RESOURCE_PROPERTY (
+ RESOURCE_ID integer not null, -- foreign key: *.RESOURCE_ID
+ NAME varchar(255) not null,
+ VALUE text not null, -- FIXME: xml?
+ VIEWER_UID varchar(255),
+
+ primary key (RESOURCE_ID, NAME, VIEWER_UID) -- implicit index
+);
+
+
+----------------------
+-- AddressBook Home --
+----------------------
+
+create table ADDRESSBOOK_HOME (
+ RESOURCE_ID integer primary key default nextval('RESOURCE_ID_SEQ'), -- implicit index
+ OWNER_UID varchar(255) not null unique, -- implicit index
+ DATAVERSION integer default 0 not null
+);
+
+-------------------------------
+-- AddressBook Home Metadata --
+-------------------------------
+
+create table ADDRESSBOOK_HOME_METADATA (
+ RESOURCE_ID integer primary key references ADDRESSBOOK_HOME on delete cascade, -- implicit index
+ QUOTA_USED_BYTES integer default 0 not null,
+ CREATED timestamp default timezone('UTC', CURRENT_TIMESTAMP),
+ MODIFIED timestamp default timezone('UTC', CURRENT_TIMESTAMP)
+);
+
+-----------------
+-- AddressBook --
+-----------------
+
+create table ADDRESSBOOK (
+ RESOURCE_ID integer primary key default nextval('RESOURCE_ID_SEQ') -- implicit index
+);
+
+
+--------------------------
+-- AddressBook Metadata --
+--------------------------
+
+create table ADDRESSBOOK_METADATA (
+ RESOURCE_ID integer primary key references ADDRESSBOOK on delete cascade, -- implicit index
+ CREATED timestamp default timezone('UTC', CURRENT_TIMESTAMP),
+ MODIFIED timestamp default timezone('UTC', CURRENT_TIMESTAMP)
+);
+
+
+----------------------
+-- AddressBook Bind --
+----------------------
+
+-- Joins ADDRESSBOOK_HOME and ADDRESSBOOK
+
+create table ADDRESSBOOK_BIND (
+ ADDRESSBOOK_HOME_RESOURCE_ID integer not null references ADDRESSBOOK_HOME,
+ ADDRESSBOOK_RESOURCE_ID integer not null references ADDRESSBOOK on delete cascade,
+ ADDRESSBOOK_RESOURCE_NAME varchar(255) not null,
+ BIND_MODE integer not null, -- enum CALENDAR_BIND_MODE
+ BIND_STATUS integer not null, -- enum CALENDAR_BIND_STATUS
+ MESSAGE text, -- FIXME: xml?
+
+ primary key (ADDRESSBOOK_HOME_RESOURCE_ID, ADDRESSBOOK_RESOURCE_ID), -- implicit index
+ unique (ADDRESSBOOK_HOME_RESOURCE_ID, ADDRESSBOOK_RESOURCE_NAME) -- implicit index
+);
+
+create index ADDRESSBOOK_BIND_RESOURCE_ID on
+ ADDRESSBOOK_BIND(ADDRESSBOOK_RESOURCE_ID);
+
+create table ADDRESSBOOK_OBJECT (
+ RESOURCE_ID integer primary key default nextval('RESOURCE_ID_SEQ'), -- implicit index
+ ADDRESSBOOK_RESOURCE_ID integer not null references ADDRESSBOOK on delete cascade,
+ RESOURCE_NAME varchar(255) not null,
+ VCARD_TEXT text not null,
+ VCARD_UID varchar(255) not null,
+ MD5 char(32) not null,
+ CREATED timestamp default timezone('UTC', CURRENT_TIMESTAMP),
+ MODIFIED timestamp default timezone('UTC', CURRENT_TIMESTAMP),
+
+ unique (ADDRESSBOOK_RESOURCE_ID, RESOURCE_NAME), -- implicit index
+ unique (ADDRESSBOOK_RESOURCE_ID, VCARD_UID) -- implicit index
+);
+
+---------------
+-- Revisions --
+---------------
+
+create sequence REVISION_SEQ;
+
+
+---------------
+-- Revisions --
+---------------
+
+create table CALENDAR_OBJECT_REVISIONS (
+ CALENDAR_HOME_RESOURCE_ID integer not null references CALENDAR_HOME,
+ CALENDAR_RESOURCE_ID integer references CALENDAR,
+ CALENDAR_NAME varchar(255) default null,
+ RESOURCE_NAME varchar(255),
+ REVISION integer default nextval('REVISION_SEQ') not null,
+ DELETED boolean not null
+);
+
+create index CALENDAR_OBJECT_REVISIONS_HOME_RESOURCE_ID_CALENDAR_RESOURCE_ID
+ on CALENDAR_OBJECT_REVISIONS(CALENDAR_HOME_RESOURCE_ID, CALENDAR_RESOURCE_ID);
+
+create index CALENDAR_OBJECT_REVISIONS_RESOURCE_ID_RESOURCE_NAME
+ on CALENDAR_OBJECT_REVISIONS(CALENDAR_RESOURCE_ID, RESOURCE_NAME);
+
+create index CALENDAR_OBJECT_REVISIONS_RESOURCE_ID_REVISION
+ on CALENDAR_OBJECT_REVISIONS(CALENDAR_RESOURCE_ID, REVISION);
+
+-------------------------------
+-- AddressBook Object Revisions --
+-------------------------------
+
+create table ADDRESSBOOK_OBJECT_REVISIONS (
+ ADDRESSBOOK_HOME_RESOURCE_ID integer not null references ADDRESSBOOK_HOME,
+ ADDRESSBOOK_RESOURCE_ID integer references ADDRESSBOOK,
+ ADDRESSBOOK_NAME varchar(255) default null,
+ RESOURCE_NAME varchar(255),
+ REVISION integer default nextval('REVISION_SEQ') not null,
+ DELETED boolean not null
+);
+
+create index ADDRESSBOOK_OBJECT_REVISIONS_HOME_RESOURCE_ID_ADDRESSBOOK_RESOURCE_ID
+ on ADDRESSBOOK_OBJECT_REVISIONS(ADDRESSBOOK_HOME_RESOURCE_ID, ADDRESSBOOK_RESOURCE_ID);
+
+create index ADDRESSBOOK_OBJECT_REVISIONS_RESOURCE_ID_RESOURCE_NAME
+ on ADDRESSBOOK_OBJECT_REVISIONS(ADDRESSBOOK_RESOURCE_ID, RESOURCE_NAME);
+
+create index ADDRESSBOOK_OBJECT_REVISIONS_RESOURCE_ID_REVISION
+ on ADDRESSBOOK_OBJECT_REVISIONS(ADDRESSBOOK_RESOURCE_ID, REVISION);
+
+-----------------------------------
+-- Notification Object Revisions --
+-----------------------------------
+
+create table NOTIFICATION_OBJECT_REVISIONS (
+ NOTIFICATION_HOME_RESOURCE_ID integer not null references NOTIFICATION_HOME on delete cascade,
+ RESOURCE_NAME varchar(255),
+ REVISION integer default nextval('REVISION_SEQ') not null,
+ DELETED boolean not null,
+
+ unique(NOTIFICATION_HOME_RESOURCE_ID, RESOURCE_NAME) -- implicit index
+);
+
+create index NOTIFICATION_OBJECT_REVISIONS_RESOURCE_ID_REVISION
+ on NOTIFICATION_OBJECT_REVISIONS(NOTIFICATION_HOME_RESOURCE_ID, REVISION);
+
+-------------------------------------------
+-- Apple Push Notification Subscriptions --
+-------------------------------------------
+
+create table APN_SUBSCRIPTIONS (
+ TOKEN varchar(255) not null,
+ RESOURCE_KEY varchar(255) not null,
+ MODIFIED integer not null,
+ SUBSCRIBER_GUID varchar(255) not null,
+ USER_AGENT varchar(255) default null,
+ IP_ADDR varchar(255) default null,
+
+ primary key (TOKEN, RESOURCE_KEY) -- implicit index
+);
+
+create index APN_SUBSCRIPTIONS_RESOURCE_KEY
+ on APN_SUBSCRIPTIONS(RESOURCE_KEY);
+
+-----------------
+-- IMIP Tokens --
+-----------------
+
+create table IMIP_TOKENS (
+ TOKEN varchar(255) not null,
+ ORGANIZER varchar(255) not null,
+ ATTENDEE varchar(255) not null,
+ ICALUID varchar(255) not null,
+ ACCESSED timestamp default timezone('UTC', CURRENT_TIMESTAMP),
+
+ primary key (ORGANIZER, ATTENDEE, ICALUID) -- implicit index
+);
+
+create index IMIP_TOKENS_TOKEN
+ on IMIP_TOKENS(TOKEN);
+
+----------------
+-- Work Items --
+----------------
+
+create sequence WORKITEM_SEQ;
+
+---------------------------
+-- IMIP Inivitation Work --
+---------------------------
+
+create table IMIP_INVITATION_WORK (
+ WORK_ID integer primary key default nextval('WORKITEM_SEQ') not null,
+ NOT_BEFORE timestamp default timezone('UTC', CURRENT_TIMESTAMP),
+ FROM_ADDR varchar(255) not null,
+ TO_ADDR varchar(255) not null,
+ ICALENDAR_TEXT text not null
+);
+
+-----------------------
+-- IMIP Polling Work --
+-----------------------
+
+create table IMIP_POLLING_WORK (
+ WORK_ID integer primary key default nextval('WORKITEM_SEQ') not null,
+ NOT_BEFORE timestamp default timezone('UTC', CURRENT_TIMESTAMP)
+);
+
+---------------------
+-- IMIP Reply Work --
+---------------------
+
+create table IMIP_REPLY_WORK (
+ WORK_ID integer primary key default nextval('WORKITEM_SEQ') not null,
+ NOT_BEFORE timestamp default timezone('UTC', CURRENT_TIMESTAMP),
+ ORGANIZER varchar(255) not null,
+ ATTENDEE varchar(255) not null,
+ ICALENDAR_TEXT text not null
+);
+
+------------------------
+-- Push Notifications --
+------------------------
+
+create table PUSH_NOTIFICATION_WORK (
+ WORK_ID integer primary key default nextval('WORKITEM_SEQ') not null,
+ NOT_BEFORE timestamp default timezone('UTC', CURRENT_TIMESTAMP),
+ PUSH_ID varchar(255) not null
+);
+
+
+--------------------
+-- Schema Version --
+--------------------
+
+create table CALENDARSERVER (
+ NAME varchar(255) primary key, -- implicit index
+ VALUE varchar(255)
+);
+
+insert into CALENDARSERVER values ('VERSION', '16');
+insert into CALENDARSERVER values ('CALENDAR-DATAVERSION', '3');
+insert into CALENDARSERVER values ('ADDRESSBOOK-DATAVERSION', '1');
Copied: CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_16_to_17.sql (from rev 10865, CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_16_to_17.sql)
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_16_to_17.sql (rev 0)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/upgrades/oracle-dialect/upgrade_from_16_to_17.sql 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,35 @@
+----
+-- Copyright (c) 2011-2013 Apple Inc. All rights reserved.
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+----
+
+---------------------------------------------------
+-- Upgrade database schema from VERSION 16 to 17 --
+---------------------------------------------------
+
+
+------------------------------
+-- CALENDAR_OBJECT clean-up --
+------------------------------
+
+alter table CALENDAR_OBJECT
+ drop (ORGANIZER_OBJECT);
+
+create index CALENDAR_OBJECT_ICALE_82e731d5 on CALENDAR_OBJECT (
+ ICALENDAR_UID
+);
+
+
+-- Now update the version
+update CALENDARSERVER set VALUE = '17' where NAME = 'VERSION';
Copied: CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/upgrades/postgres-dialect/upgrade_from_16_to_17.sql (from rev 10865, CalendarServer/trunk/txdav/common/datastore/sql_schema/upgrades/postgres-dialect/upgrade_from_16_to_17.sql)
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/upgrades/postgres-dialect/upgrade_from_16_to_17.sql (rev 0)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/sql_schema/upgrades/postgres-dialect/upgrade_from_16_to_17.sql 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,34 @@
+----
+-- Copyright (c) 2011-2013 Apple Inc. All rights reserved.
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+----
+
+---------------------------------------------------
+-- Upgrade database schema from VERSION 16 to 17 --
+---------------------------------------------------
+
+
+------------------------------
+-- CALENDAR_OBJECT clean-up --
+------------------------------
+
+alter table CALENDAR_OBJECT
+ drop column ORGANIZER_OBJECT;
+
+create index CALENDAR_OBJECT_ICALENDAR_UID on
+ CALENDAR_OBJECT(ICALENDAR_UID);
+
+
+-- Now update the version
+update CALENDARSERVER set VALUE = '17' where NAME = 'VERSION';
Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/test/util.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/test/util.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/test/util.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -14,44 +14,52 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##
+
"""
Store test utility functions
"""
-import gc
+from __future__ import print_function
+
+from calendarserver.push.notifier import Notifier
+
from hashlib import md5
+
+from pycalendar.datetime import PyCalendarDateTime
+
from random import Random
-from zope.interface.verify import verifyObject
-from zope.interface.exceptions import BrokenMethodImplementation, \
- DoesNotImplement
+from twext.enterprise.adbapi2 import ConnectionPool
+from twext.enterprise.ienterprise import AlreadyFinishedError
from twext.python.filepath import CachingFilePath
from twext.python.vcomponent import VComponent
from twext.web2.dav.resource import TwistedGETContentMD5
+from twisted.application.service import Service
from twisted.internet import reactor
from twisted.internet.defer import Deferred, inlineCallbacks
+from twisted.internet.defer import returnValue
from twisted.internet.task import deferLater
from twisted.python import log
-from twisted.application.service import Service
+from twisted.trial.unittest import TestCase
from twistedcaldav.config import config
+from twistedcaldav.stdconfig import DEFAULT_CONFIG
+from twistedcaldav.vcard import Component as ABComponent
-from txdav.common.datastore.sql import CommonDataStore, current_sql_schema
+from txdav.base.datastore.dbapiclient import DiagnosticConnectionWrapper
from txdav.base.datastore.subpostgres import PostgresService
-from txdav.base.datastore.dbapiclient import DiagnosticConnectionWrapper
from txdav.base.propertystore.base import PropertyName
+from txdav.common.datastore.sql import CommonDataStore, current_sql_schema
+from txdav.common.datastore.sql_tables import schema
from txdav.common.icommondatastore import NoSuchHomeChildError
-from twext.enterprise.adbapi2 import ConnectionPool
-from twisted.trial.unittest import TestCase
-from twisted.internet.defer import returnValue
-from calendarserver.push.notifier import Notifier
-from twext.enterprise.ienterprise import AlreadyFinishedError
-from twistedcaldav.vcard import Component as ABComponent
-from pycalendar.datetime import PyCalendarDateTime
-from txdav.common.datastore.sql_tables import schema
+from zope.interface.exceptions import BrokenMethodImplementation, \
+ DoesNotImplement
+from zope.interface.verify import verifyObject
+import gc
+
md5key = PropertyName.fromElement(TwistedGETContentMD5)
def allInstancesOf(cls):
@@ -71,10 +79,10 @@
between tests. (It is currently not invoked anywhere, but may be useful if
these types of bugs crop up in the future.)
"""
- print '+++ ALL CONNECTIONS +++'
+ print("+++ ALL CONNECTIONS +++")
for connection in allInstancesOf(DiagnosticConnectionWrapper):
- print connection.label, connection.state
- print '--- CONNECTIONS END ---'
+ print(connection.label, connection.state)
+ print("--- CONNECTIONS END ---")
@@ -646,7 +654,6 @@
-
class StubNotifierFactory(object):
"""
For testing push notifications without an XMPP server.
@@ -698,6 +705,8 @@
from twistedcaldav.memcacher import Memcacher
+ if not hasattr(config, "Memcached"):
+ config.setDefaults(DEFAULT_CONFIG)
aTest.patch(config.Memcached.Pools.Default, "ClientEnabled", False)
aTest.patch(config.Memcached.Pools.Default, "ServerEnabled", False)
aTest.patch(Memcacher, "allowTestCache", True)
Added: CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/upgrade/sql/others/test/__init__.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/upgrade/sql/others/test/__init__.py (rev 0)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/upgrade/sql/others/test/__init__.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,15 @@
+##
+# Copyright (c) 2013 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
Added: CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/upgrade/sql/others/test/test_attachment_migration.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/upgrade/sql/others/test/test_attachment_migration.py (rev 0)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/upgrade/sql/others/test/test_attachment_migration.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -0,0 +1,177 @@
+##
+# Copyright (c) 2010-2013 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+from twext.enterprise.dal.syntax import Delete
+
+from twisted.internet.defer import inlineCallbacks, succeed, returnValue
+from twisted.trial.unittest import TestCase
+
+from twistedcaldav.config import config
+
+from txdav.caldav.datastore.sql import CalendarStoreFeatures
+from txdav.common.datastore.sql_tables import schema
+from txdav.common.datastore.test.util import theStoreBuilder, \
+ StubNotifierFactory
+from txdav.common.datastore.upgrade.sql.others import attachment_migration
+from txdav.common.datastore.upgrade.sql.upgrade import UpgradeDatabaseOtherService
+
+"""
+Tests for L{txdav.common.datastore.upgrade.sql.upgrade}.
+"""
+
+
+class AttachmentMigrationTests(TestCase):
+ """
+ Tests for L{UpgradeDatabaseSchemaService}.
+ """
+
+ @inlineCallbacks
+ def _initStore(self, enableManagedAttachments=True):
+ """
+ Build a store with certain bits cleaned out.
+ """
+
+ self.patch(config, "EnableManagedAttachments", enableManagedAttachments)
+
+ store = yield theStoreBuilder.buildStore(
+ self, StubNotifierFactory()
+ )
+ store.enableManagedAttachments = enableManagedAttachments
+
+ txn = store.newTransaction()
+ cs = schema.CALENDARSERVER
+ yield Delete(
+ From=cs,
+ Where=cs.NAME == "MANAGED-ATTACHMENTS"
+ ).on(txn)
+ yield txn.commit()
+
+ returnValue(store)
+
+
+ @inlineCallbacks
+ def test_upgradeFromEmptyDropbox(self):
+ """
+ Test L{attachment_migration.doUpgrade} when managed attachments is enabled and dropbox items do not exist.
+ """
+
+ didUpgrade = [False, ]
+ def _hasDropboxAttachments(_self, txn):
+ return succeed(False)
+ self.patch(CalendarStoreFeatures, "hasDropboxAttachments", _hasDropboxAttachments)
+
+ def _upgradeToManagedAttachments(_self, batchSize=10):
+ didUpgrade[0] = True
+ return succeed(None)
+ self.patch(CalendarStoreFeatures, "upgradeToManagedAttachments", _upgradeToManagedAttachments)
+
+ store = (yield self._initStore())
+
+ upgrader = UpgradeDatabaseOtherService(store, None)
+ yield attachment_migration.doUpgrade(upgrader)
+ self.assertFalse(didUpgrade[0])
+
+ txn = upgrader.sqlStore.newTransaction()
+ managed = (yield txn.calendarserverValue("MANAGED-ATTACHMENTS", raiseIfMissing=False))
+ yield txn.commit()
+ self.assertNotEqual(managed, None)
+
+
+ @inlineCallbacks
+ def test_upgradeFromDropboxOK(self):
+ """
+ Test L{attachment_migration.doUpgrade} when managed attachments is enabled and dropbox items exist.
+ """
+
+ didUpgrade = [False, ]
+ def _hasDropboxAttachments(_self, txn):
+ return succeed(True)
+ self.patch(CalendarStoreFeatures, "hasDropboxAttachments", _hasDropboxAttachments)
+
+ def _upgradeToManagedAttachments(_self, batchSize=10):
+ didUpgrade[0] = True
+ return succeed(None)
+ self.patch(CalendarStoreFeatures, "upgradeToManagedAttachments", _upgradeToManagedAttachments)
+
+ store = (yield self._initStore())
+
+ upgrader = UpgradeDatabaseOtherService(store, None)
+ yield attachment_migration.doUpgrade(upgrader)
+ self.assertTrue(didUpgrade[0])
+
+ txn = upgrader.sqlStore.newTransaction()
+ managed = (yield txn.calendarserverValue("MANAGED-ATTACHMENTS", raiseIfMissing=False))
+ yield txn.commit()
+ self.assertNotEqual(managed, None)
+
+
+ @inlineCallbacks
+ def test_upgradeAlreadyDone(self):
+ """
+ Test L{attachment_migration.doUpgrade} when managed attachments is enabled and migration already done.
+ """
+
+ didUpgrade = [False, ]
+ def _hasDropboxAttachments(_self, txn):
+ return succeed(True)
+ self.patch(CalendarStoreFeatures, "hasDropboxAttachments", _hasDropboxAttachments)
+
+ def _upgradeToManagedAttachments(_self, batchSize=10):
+ didUpgrade[0] = True
+ return succeed(None)
+ self.patch(CalendarStoreFeatures, "upgradeToManagedAttachments", _upgradeToManagedAttachments)
+
+ store = (yield self._initStore())
+ txn = store.newTransaction()
+ yield txn.setCalendarserverValue("MANAGED-ATTACHMENTS", "1")
+ yield txn.commit()
+
+ upgrader = UpgradeDatabaseOtherService(store, None)
+ yield attachment_migration.doUpgrade(upgrader)
+ self.assertFalse(didUpgrade[0])
+
+ txn = upgrader.sqlStore.newTransaction()
+ managed = (yield txn.calendarserverValue("MANAGED-ATTACHMENTS", raiseIfMissing=False))
+ yield txn.commit()
+ self.assertNotEqual(managed, None)
+
+
+ @inlineCallbacks
+ def test_upgradeNotEnabled(self):
+ """
+ Test L{attachment_migration.doUpgrade} when managed attachments is disabled.
+ """
+
+ didUpgrade = [False, ]
+ def _hasDropboxAttachments(_self, txn):
+ return succeed(True)
+ self.patch(CalendarStoreFeatures, "hasDropboxAttachments", _hasDropboxAttachments)
+
+ def _upgradeToManagedAttachments(_self, batchSize=10):
+ didUpgrade[0] = True
+ return succeed(None)
+ self.patch(CalendarStoreFeatures, "upgradeToManagedAttachments", _upgradeToManagedAttachments)
+
+ store = (yield self._initStore(False))
+
+ upgrader = UpgradeDatabaseOtherService(store, None)
+ yield attachment_migration.doUpgrade(upgrader)
+ self.assertFalse(didUpgrade[0])
+
+ txn = upgrader.sqlStore.newTransaction()
+ managed = (yield txn.calendarserverValue("MANAGED-ATTACHMENTS", raiseIfMissing=False))
+ yield txn.commit()
+ self.assertEqual(managed, None)
Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/upgrade/sql/test/test_upgrade.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/upgrade/sql/test/test_upgrade.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/upgrade/sql/test/test_upgrade.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -23,7 +23,7 @@
from twisted.python.modules import getModule
from twisted.trial.unittest import TestCase
from txdav.common.datastore.test.util import theStoreBuilder, StubNotifierFactory
-from txdav.common.datastore.upgrade.sql.upgrade import UpgradeDatabaseSchemaService,\
+from txdav.common.datastore.upgrade.sql.upgrade import UpgradeDatabaseSchemaService, \
UpgradeDatabaseDataService
import re
@@ -42,19 +42,20 @@
return 1
return int(found.group(2))
+
def test_scanUpgradeFiles(self):
-
+
upgrader = UpgradeDatabaseSchemaService(None, None)
upgrader.schemaLocation = getModule(__name__).filePath.sibling("fake_schema1")
files = upgrader.scanForUpgradeFiles("fake_dialect")
- self.assertEqual(files,
+ self.assertEqual(files,
[(3, 4, upgrader.schemaLocation.child("upgrades").child("fake_dialect").child("upgrade_from_3_to_4.sql"))],
)
upgrader.schemaLocation = getModule(__name__).filePath.sibling("fake_schema2")
files = upgrader.scanForUpgradeFiles("fake_dialect")
- self.assertEqual(files,
+ self.assertEqual(files,
[
(3, 4, upgrader.schemaLocation.child("upgrades").child("fake_dialect").child("upgrade_from_3_to_4.sql")),
(3, 5, upgrader.schemaLocation.child("upgrades").child("fake_dialect").child("upgrade_from_3_to_5.sql")),
@@ -62,14 +63,15 @@
]
)
+
def test_determineUpgradeSequence(self):
-
+
upgrader = UpgradeDatabaseSchemaService(None, None)
upgrader.schemaLocation = getModule(__name__).filePath.sibling("fake_schema1")
files = upgrader.scanForUpgradeFiles("fake_dialect")
upgrades = upgrader.determineUpgradeSequence(3, 4, files, "fake_dialect")
- self.assertEqual(upgrades,
+ self.assertEqual(upgrades,
[upgrader.schemaLocation.child("upgrades").child("fake_dialect").child("upgrade_from_3_to_4.sql")],
)
self.assertRaises(RuntimeError, upgrader.determineUpgradeSequence, 3, 5, files, "fake_dialect")
@@ -77,35 +79,36 @@
upgrader.schemaLocation = getModule(__name__).filePath.sibling("fake_schema2")
files = upgrader.scanForUpgradeFiles("fake_dialect")
upgrades = upgrader.determineUpgradeSequence(3, 5, files, "fake_dialect")
- self.assertEqual(upgrades,
+ self.assertEqual(upgrades,
[upgrader.schemaLocation.child("upgrades").child("fake_dialect").child("upgrade_from_3_to_5.sql")]
)
upgrades = upgrader.determineUpgradeSequence(4, 5, files, "fake_dialect")
- self.assertEqual(upgrades,
+ self.assertEqual(upgrades,
[upgrader.schemaLocation.child("upgrades").child("fake_dialect").child("upgrade_from_4_to_5.sql")]
)
upgrader.schemaLocation = getModule(__name__).filePath.sibling("fake_schema3")
files = upgrader.scanForUpgradeFiles("fake_dialect")
upgrades = upgrader.determineUpgradeSequence(3, 5, files, "fake_dialect")
- self.assertEqual(upgrades,
+ self.assertEqual(upgrades,
[
upgrader.schemaLocation.child("upgrades").child("fake_dialect").child("upgrade_from_3_to_4.sql"),
upgrader.schemaLocation.child("upgrades").child("fake_dialect").child("upgrade_from_4_to_5.sql"),
]
)
+
def test_upgradeAvailability(self):
"""
Make sure that each old schema has a valid upgrade path to the current one.
"""
-
+
for dialect in (POSTGRES_DIALECT, ORACLE_DIALECT,):
upgrader = UpgradeDatabaseSchemaService(None, None)
files = upgrader.scanForUpgradeFiles(dialect)
current_version = self._getSchemaVersion(upgrader.schemaLocation.child("current.sql"), "VERSION")
-
+
for child in upgrader.schemaLocation.child("old").child(dialect).globChildren("*.sql"):
old_version = self._getSchemaVersion(child, "VERSION")
upgrades = upgrader.determineUpgradeSequence(old_version, current_version, files, dialect)
@@ -115,7 +118,7 @@
# """
# Make sure that each upgrade file has a valid data upgrade file or None.
# """
-#
+#
# for dialect in (POSTGRES_DIALECT, ORACLE_DIALECT,):
# upgrader = UpgradeDatabaseSchemaService(None, None)
# files = upgrader.scanForUpgradeFiles(dialect)
@@ -124,6 +127,7 @@
# if result is not None:
# self.assertIsInstance(result, types.FunctionType)
+
@inlineCallbacks
def test_dbSchemaUpgrades(self):
"""
@@ -142,7 +146,7 @@
Use the postgres schema mechanism to do tests under a separate "namespace"
in postgres that we can quickly wipe clean afterwards.
"""
- startTxn = store.newTransaction("test_dbUpgrades")
+ startTxn = store.newTransaction("test_dbUpgrades")
yield startTxn.execSQL("create schema test_dbUpgrades;")
yield startTxn.execSQL("set search_path to test_dbUpgrades;")
yield startTxn.execSQL(path.getContent())
@@ -150,21 +154,21 @@
@inlineCallbacks
def _loadVersion():
- startTxn = store.newTransaction("test_dbUpgrades")
+ startTxn = store.newTransaction("test_dbUpgrades")
new_version = yield startTxn.execSQL("select value from calendarserver where name = 'VERSION';")
yield startTxn.commit()
returnValue(int(new_version[0][0]))
@inlineCallbacks
def _unloadOldSchema():
- startTxn = store.newTransaction("test_dbUpgrades")
+ startTxn = store.newTransaction("test_dbUpgrades")
yield startTxn.execSQL("set search_path to public;")
yield startTxn.execSQL("drop schema test_dbUpgrades cascade;")
yield startTxn.commit()
@inlineCallbacks
def _cleanupOldSchema():
- startTxn = store.newTransaction("test_dbUpgrades")
+ startTxn = store.newTransaction("test_dbUpgrades")
yield startTxn.execSQL("set search_path to public;")
yield startTxn.execSQL("drop schema if exists test_dbUpgrades cascade;")
yield startTxn.commit()
@@ -174,6 +178,8 @@
test_upgrader = UpgradeDatabaseSchemaService(None, None)
expected_version = self._getSchemaVersion(test_upgrader.schemaLocation.child("current.sql"), "VERSION")
for child in test_upgrader.schemaLocation.child("old").child(POSTGRES_DIALECT).globChildren("*.sql"):
+
+ # Upgrade allowed
upgrader = UpgradeDatabaseSchemaService(store, None)
yield _loadOldSchema(child)
yield upgrader.databaseUpgrade()
@@ -182,13 +188,31 @@
self.assertEqual(new_version, expected_version)
+ # Upgrade disallowed
+ upgrader = UpgradeDatabaseSchemaService(store, None, failIfUpgradeNeeded=True, stopOnFail=False)
+ yield _loadOldSchema(child)
+ old_version = yield _loadVersion()
+ try:
+ yield upgrader.databaseUpgrade()
+ except RuntimeError:
+ pass
+ except Exception:
+ self.fail("RuntimeError not raised")
+ else:
+ self.fail("RuntimeError not raised")
+ new_version = yield _loadVersion()
+ yield _unloadOldSchema()
+
+ self.assertEqual(old_version, new_version)
+
+
@inlineCallbacks
def test_dbDataUpgrades(self):
"""
This does a full DB test of all possible data upgrade paths. For each old schema, it loads it into the DB
then runs the data upgrade service. This ensures all the upgrade_XX.py files work correctly - at least for
postgres.
-
+
TODO: this currently does not create any calendar data to test with. It simply runs the upgrade on an empty
store.
"""
@@ -203,7 +227,7 @@
Use the postgres schema mechanism to do tests under a separate "namespace"
in postgres that we can quickly wipe clean afterwards.
"""
- startTxn = store.newTransaction("test_dbUpgrades")
+ startTxn = store.newTransaction("test_dbUpgrades")
yield startTxn.execSQL("create schema test_dbUpgrades;")
yield startTxn.execSQL("set search_path to test_dbUpgrades;")
yield startTxn.execSQL(path.getContent())
@@ -212,21 +236,21 @@
@inlineCallbacks
def _loadVersion():
- startTxn = store.newTransaction("test_dbUpgrades")
+ startTxn = store.newTransaction("test_dbUpgrades")
new_version = yield startTxn.execSQL("select value from calendarserver where name = 'CALENDAR-DATAVERSION';")
yield startTxn.commit()
returnValue(int(new_version[0][0]))
@inlineCallbacks
def _unloadOldData():
- startTxn = store.newTransaction("test_dbUpgrades")
+ startTxn = store.newTransaction("test_dbUpgrades")
yield startTxn.execSQL("set search_path to public;")
yield startTxn.execSQL("drop schema test_dbUpgrades cascade;")
yield startTxn.commit()
@inlineCallbacks
def _cleanupOldData():
- startTxn = store.newTransaction("test_dbUpgrades")
+ startTxn = store.newTransaction("test_dbUpgrades")
yield startTxn.execSQL("set search_path to public;")
yield startTxn.execSQL("drop schema if exists test_dbUpgrades cascade;")
yield startTxn.commit()
Modified: CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/upgrade/sql/upgrade.py
===================================================================
--- CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/upgrade/sql/upgrade.py 2013-03-07 21:36:39 UTC (rev 10866)
+++ CalendarServer/branches/users/gaya/sharedgroups/txdav/common/datastore/upgrade/sql/upgrade.py 2013-03-07 22:42:21 UTC (rev 10867)
@@ -52,7 +52,7 @@
"""
@classmethod
- def wrapService(cls, service, store, uid=None, gid=None):
+ def wrapService(cls, service, store, uid=None, gid=None, **kwargs):
"""
Create an L{UpgradeDatabaseSchemaService} when starting the database
so we can check the schema version and do any upgrades.
@@ -73,10 +73,10 @@
@return: a service
@rtype: L{IService}
"""
- return cls(store, service, uid=uid, gid=gid,)
+ return cls(store, service, uid=uid, gid=gid, **kwargs)
- def __init__(self, sqlStore, service, uid=None, gid=None):
+ def __init__(self, sqlStore, service, uid=None, gid=None, failIfUpgradeNeeded=False, stopOnFail=True):
"""
Initialize the service.
"""
@@ -84,6 +84,8 @@
self.sqlStore = sqlStore
self.uid = uid
self.gid = gid
+ self.failIfUpgradeNeeded = failIfUpgradeNeeded
+ self.stopOnFail = stopOnFail
self.schemaLocation = getModule(__name__).filePath.parent().parent().sibling("sql_schema")
self.pyLocation = getModule(__name__).filePath.parent()
@@ -118,6 +120,10 @@
)
self.log_error(msg)
raise RuntimeError(msg)
+ elif self.failIfUpgradeNeeded:
+ if self.stopOnFail:
+ reactor.stop()
+ raise RuntimeError("Database upgrade is needed but not allowed.")
else:
self.sqlStore.setUpgrading(True)
yield self.upgradeVersion(actual_version, required_version, dialect)
@@ -275,14 +281,14 @@
@type wrappedService: L{IService} or C{NoneType}
"""
- def __init__(self, sqlStore, service, uid=None, gid=None):
+ def __init__(self, sqlStore, service, **kwargs):
"""
Initialize the service.
@param sqlStore: The store to operate on. Can be C{None} when doing unit tests.
@param service: Wrapped service. Can be C{None} when doing unit tests.
"""
- super(UpgradeDatabaseSchemaService, self).__init__(sqlStore, service, uid, gid)
+ super(UpgradeDatabaseSchemaService, self).__init__(sqlStore, service, **kwargs)
self.versionKey = "VERSION"
self.versionDescriptor = "schema"
@@ -328,14 +334,14 @@
@type wrappedService: L{IService} or C{NoneType}
"""
- def __init__(self, sqlStore, service, uid=None, gid=None):
+ def __init__(self, sqlStore, service, **kwargs):
"""
Initialize the service.
@param sqlStore: The store to operate on. Can be C{None} when doing unit tests.
@param service: Wrapped service. Can be C{None} when doing unit tests.
"""
- super(UpgradeDatabaseDataService, self).__init__(sqlStore, service, uid, gid)
+ super(UpgradeDatabaseDataService, self).__init__(sqlStore, service, **kwargs)
self.versionKey = "CALENDAR-DATAVERSION"
self.versionDescriptor = "data"
@@ -380,14 +386,14 @@
@type wrappedService: L{IService} or C{NoneType}
"""
- def __init__(self, sqlStore, service, uid=None, gid=None):
+ def __init__(self, sqlStore, service, **kwargs):
"""
Initialize the service.
@param sqlStore: The store to operate on. Can be C{None} when doing unit tests.
@param service: Wrapped service. Can be C{None} when doing unit tests.
"""
- super(UpgradeDatabaseOtherService, self).__init__(sqlStore, service, uid, gid)
+ super(UpgradeDatabaseOtherService, self).__init__(sqlStore, service, **kwargs)
self.versionDescriptor = "other upgrades"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20130307/7bc9f484/attachment-0001.html>
More information about the calendarserver-changes
mailing list