[CalendarServer-changes] [14580] CalendarServer/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Thu Mar 12 12:50:10 PDT 2015
Revision: 14580
http://trac.calendarserver.org//changeset/14580
Author: sagen at apple.com
Date: 2015-03-12 12:50:10 -0700 (Thu, 12 Mar 2015)
Log Message:
-----------
When listing trashed events, results are sorted by most-recently-trashed-first, and for repeating events, the upcoming three instances are displayed. Locations are now included, as well as displaying the start time for each event in the TZ of the event itself.
Modified Paths:
--------------
CalendarServer/trunk/calendarserver/tools/trash.py
CalendarServer/trunk/txdav/caldav/datastore/sql.py
Modified: CalendarServer/trunk/calendarserver/tools/trash.py
===================================================================
--- CalendarServer/trunk/calendarserver/tools/trash.py 2015-03-12 19:48:52 UTC (rev 14579)
+++ CalendarServer/trunk/calendarserver/tools/trash.py 2015-03-12 19:50:10 UTC (rev 14580)
@@ -22,6 +22,7 @@
from calendarserver.tools.cmdline import utilityMain, WorkerService
from calendarserver.tools.util import prettyRecord
+from pycalendar.datetime import DateTime, Timezone
from twext.python.log import Logger
from twisted.internet.defer import inlineCallbacks, returnValue
from txdav.base.propertystore.base import PropertyName
@@ -141,7 +142,38 @@
yield store.inTransaction(label="List trashed collections", operation=doIt)
+def agoString(delta):
+ if delta.days:
+ agoString = "{} days ago".format(delta.days)
+ elif delta.seconds:
+ if delta.seconds < 60:
+ agoString = "{} second{} ago".format(delta.seconds, "s" if delta.seconds > 1 else "")
+ else:
+ minutesAgo = delta.seconds / 60
+ if minutesAgo < 60:
+ agoString = "{} minute{} ago".format(minutesAgo, "s" if minutesAgo > 1 else "")
+ else:
+ hoursAgo = minutesAgo / 60
+ agoString = "{} hour{} ago".format(hoursAgo, "s" if hoursAgo > 1 else "")
+ return agoString
+
+def startString(pydt):
+ return pydt.getLocaleDateTime(DateTime.FULLDATE, False, True, pydt.getTimezoneID())
+
+
+def locationString(component):
+ locationProps = component.properties("LOCATION")
+ if locationProps is not None:
+ locations = []
+ for locationProp in locationProps:
+ locations.append(locationProp.value())
+ locationString = ", ".join(locations)
+ else:
+ locationString = ""
+ return locationString
+
+
@inlineCallbacks
def listTrashedEventsForPrincipal(service, store, principalUID):
directory = store.directoryService()
@@ -168,23 +200,68 @@
print("No untrashed collections for:", prettyRecord(record))
returnValue(None)
+ oneYearInFuture = DateTime.getNowUTC()
+ oneYearInFuture.offsetDay(365)
+
+ nowPyDT = DateTime.getNowUTC()
+
+ nowDT = datetime.datetime.utcnow()
+
for collection in untrashedCollections:
displayName = displayNameForCollection(collection)
children = yield trash.trashForCollection(collection._resourceID)
if len(children) == 0:
continue
- print("Collection = \"{}\"".format(displayName.encode("utf-8")))
+ print("Trashed events in calendar \"{}\":".format(displayName.encode("utf-8")))
for child in children:
+ print()
component = yield child.component()
- summary = component.mainComponent().propertyValue("SUMMARY", "<no title>")
+
+ mainSummary = component.mainComponent().propertyValue("SUMMARY", u"<no title>")
whenTrashed = yield child.whenTrashed()
- print(
- " \"{}\", trashed = {}, id = {}".format(
- summary.encode("utf-8"), whenTrashed, child._resourceID
+ ago = nowDT - whenTrashed
+ print(" Trashed {}:".format(agoString(ago)))
+
+ if component.isRecurring():
+ print(
+ " \"{}\" (repeating) Recovery ID = {}".format(
+ mainSummary, child._resourceID
+ )
)
- )
+ print(" ...upcoming instances:")
+ instances = component.cacheExpandedTimeRanges(oneYearInFuture)
+ instances = sorted(instances.instances.values(), key=lambda x: x.start)
+ limit = 3
+ count = 0
+ for instance in instances:
+ if instance.start >= nowPyDT:
+ summary = instance.component.propertyValue("SUMMARY", u"<no title>")
+ location = locationString(instance.component)
+ tzid = instance.component.getProperty("DTSTART").parameterValue("TZID", None)
+ dtstart = instance.start
+ if tzid is not None:
+ timezone = Timezone(tzid=tzid)
+ dtstart.adjustTimezone(timezone)
+ print(" \"{}\" {} {}".format(summary, startString(dtstart), location))
+ count += 1
+ limit -= 1
+ if limit == 0:
+ break
+ if not count:
+ print(" (none)")
+ else:
+ print(
+ " \"{}\" (non-repeating) Recovery ID = {}".format(
+ mainSummary, child._resourceID
+ )
+ )
+ dtstart = component.mainComponent().propertyValue("DTSTART")
+ location = locationString(component.mainComponent())
+ print(" {} {}".format(startString(dtstart), location))
+
+
yield store.inTransaction(label="List trashed events", operation=doIt)
Modified: CalendarServer/trunk/txdav/caldav/datastore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/caldav/datastore/sql.py 2015-03-12 19:48:52 UTC (rev 14579)
+++ CalendarServer/trunk/txdav/caldav/datastore/sql.py 2015-03-12 19:50:10 UTC (rev 14580)
@@ -5159,6 +5159,8 @@
obj.ORIGINAL_COLLECTION == Parameter("resourceID")).And(
obj.TRASHED >= Parameter("start")).And(
obj.TRASHED <= Parameter("end")),
+ OrderBy=obj.TRASHED,
+ Ascending=False
)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20150312/4b2b784e/attachment-0001.html>
More information about the calendarserver-changes
mailing list