[CalendarServer-changes] [543]
CalendarServer/branches/caladmin-tool/caladmin
source_changes at macosforge.org
source_changes at macosforge.org
Tue Nov 21 15:04:21 PST 2006
Revision: 543
http://trac.macosforge.org/projects/calendarserver/changeset/543
Author: dreid at apple.com
Date: 2006-11-21 15:04:20 -0800 (Tue, 21 Nov 2006)
Log Message:
-----------
update commands to not import their actions until they're actually called, this will speed up loading of everything. Have script.py read in the config file merge it with the default and do some magic stuff. (this is probably broken if you actually specify --config.) make purge with the new script and commands.
Modified Paths:
--------------
CalendarServer/branches/caladmin-tool/caladmin/commands.py
CalendarServer/branches/caladmin-tool/caladmin/purge.py
CalendarServer/branches/caladmin-tool/caladmin/script.py
Modified: CalendarServer/branches/caladmin-tool/caladmin/commands.py
===================================================================
--- CalendarServer/branches/caladmin-tool/caladmin/commands.py 2006-11-21 20:16:55 UTC (rev 542)
+++ CalendarServer/branches/caladmin-tool/caladmin/commands.py 2006-11-21 23:04:20 UTC (rev 543)
@@ -38,12 +38,8 @@
yield [command.name, command.shortcut, command, command.help]
-# Some common parameter definitions
+from twisted.python import reflect
-PARAM_DOCROOT = ['docroot', 'D', '/Library/CalendarServer/Documents',
- 'Document root for the calendar server data to back up.']
-
-
class SubCommand(usage.Options):
name = None
shortcut = None
@@ -52,76 +48,96 @@
params = ()
+ def __init__(self):
+ self._action = reflect.namedAny(self.action)
+ usage.Options.__init__(self)
+
def parseArgs(self, *rest):
self.params += rest
def postOptions(self):
- self.action(self).run()
+ self._action(self).run()
-from twisted.internet import reactor
-from twisted.internet.defer import maybeDeferred
-from twisted.python.failure import Failure
+class QuotaOptions(SubCommand):
+ name = 'quotas'
+ help = 'Retrieve quota information for principals'
+ action = 'caladmin.quotas.QuotaAction'
+
+ def __init__(self):
+ SubCommand.__init__(self)
-class TwistedSubCommand(SubCommand):
- """Subcommand subclass that calls it's action's run method from within a
- reactor."""
+ self['types'] = []
- def postOptions(self):
+ def opt_users(self):
+ """Show Quotas for user calendars.
+ """
+
+ self['types'].append('users')
+ opt_u = opt_users
- def _log(failure):
- failure.printTraceback()
+ def opt_groups(self):
+ """Show Quotas for group calendars.
+ """
+
+ self['types'].append('groups')
+ opt_g = opt_groups
- def _runRun():
- try:
- d = maybeDeferred(self.action(self).run)
- d.addErrback(_log).addBoth(lambda _: reactor.stop())
- except:
- failure = Failure()
- failure.printTraceback()
+ def opt_resources(self):
+ """Show Quotas for resource calendars.
+ """
+
+ self['types'].append('resources')
+ opt_r = opt_resources
- reactor.stop()
+registerCommand(QuotaOptions)
- reactor.callLater(0, _runRun)
- reactor.run()
-
-from caladmin.users import UserAction
-
-class UserOptions(TwistedSubCommand):
+class UserOptions(SubCommand):
name = 'users'
help = 'Retrieve information about and perform actions on users.'
- action = UserAction
+ action = 'caladmin.users.UserAction'
optFlags = [
['list', '1', 'List only usernames, one per line.'],
- ['disabled', 'd', 'Limit display to disabled users.']
+ ['disabled', 'd', 'Limit display to disabled users.'],
+ ['detailed', None, 'Detailed statistics for each account.'],
]
- optParameters = [
- ['server', 's', 'http://localhost:8008/',
- 'The url of the calendar server to query for user information.'],
- ['username', 'u', None,
- 'The username to connect to the calendar server'],
- ['password', 'p', None,
- 'The password'],
- ]
-
registerCommand(UserOptions)
-from purge import PurgeAction
-
class PurgeOptions(SubCommand):
name = 'purge'
help = ('Keep your store from becoming unnecessarily large by purging '
'old events.')
- action = PurgeAction
+ action = 'caladmin.purge.PurgeAction'
optParameters = [
['days', 'n', 30, 'Age threshold for purging events.'],
- PARAM_DOCROOT
]
registerCommand(PurgeOptions)
+
+
+class StatsOptions(SubCommand):
+ name = 'stats'
+ help = ('Overall usage statistics.')
+ action = 'caladmin.stats.StatsAction'
+
+
+registerCommand(StatsOptions)
+
+
+class LogOptions(SubCommand):
+ name = 'logs'
+ help = ('Gather and report useful information from the logfiles.')
+ action = 'caladmin.logs.LogAction'
+
+ optParameters = [
+ ['logfile', 'L', '/var/caldavd/server.log',
+ 'Path to the log file to analyze'],
+ ]
+
+registerCommand(LogOptions)
Modified: CalendarServer/branches/caladmin-tool/caladmin/purge.py
===================================================================
--- CalendarServer/branches/caladmin-tool/caladmin/purge.py 2006-11-21 20:16:55 UTC (rev 542)
+++ CalendarServer/branches/caladmin-tool/caladmin/purge.py 2006-11-21 23:04:20 UTC (rev 543)
@@ -20,7 +20,7 @@
import datetime, dateutil.tz
-def purge(collection, purgeDate):
+def purgeEvents(collection, purgeDate):
"""
Recursively purge all events older than purgeDate.
@@ -34,37 +34,29 @@
from twistedcaldav import ical
- collection = os.path.abspath(collection)
-
files = []
directories = []
- for child in os.listdir(collection):
- if child == '.db.sqlite':
+ for child in collection.children():
+ if child.basename() == '.db.sqlite':
continue
- child = os.path.join(collection, child)
-
- if os.path.isdir(child):
+ if child.isdir():
directories.append(child)
- elif os.path.isfile(child):
+ elif child.isfile():
files.append(child)
for directory in directories:
- purge(directory, purgeDate)
+ purgeEvents(directory, purgeDate)
- for fname in files:
- f = open(fname)
-
+ for f in files:
try:
- component = ical.Component.fromStream(f)
+ component = ical.Component.fromStream(f.open())
except ValueError:
# Not a calendar file?
continue
- f.close()
-
endDate = component.mainComponent().getEndDateUTC()
if component.resourceType() == 'VTODO':
@@ -81,35 +73,27 @@
print "Purging %s, %s, %s" % (component.resourceType(),
component.resourceUID(),
endDate.isoformat())
- os.remove(fname)
+ f.remove()
class PurgeAction(object):
def __init__(self, config):
self.config = config
+ self.calendarCollection = config.parent.calendarCollection
def run(self):
- assert os.path.exists(self.config['docroot'])
-
- calendarCollectionRoot = os.path.join(
- os.path.abspath(self.config['docroot']),
- 'calendars')
-
if self.config.params:
- collections = [os.path.join(calendarCollectionRoot, p)
+ collections = [self.calendarCollection.child(p)
for p in self.config.params]
else:
collections = []
-
- for type in os.listdir(calendarCollectionRoot):
- tRoot = os.path.join(calendarCollectionRoot, type)
-
- for collection in os.listdir(tRoot):
- collections.append(os.path.join(tRoot, collection))
-
+
+ for type in self.calendarCollection.children():
+ collections.extend(type.children())
+
purgeDate = datetime.date.today()
purgeDate = purgeDate - datetime.timedelta(self.config['days'])
for collection in collections:
- purge(collection, purgeDate)
+ purgeEvents(collection, purgeDate)
Modified: CalendarServer/branches/caladmin-tool/caladmin/script.py
===================================================================
--- CalendarServer/branches/caladmin-tool/caladmin/script.py 2006-11-21 20:16:55 UTC (rev 542)
+++ CalendarServer/branches/caladmin-tool/caladmin/script.py 2006-11-21 23:04:20 UTC (rev 543)
@@ -31,7 +31,10 @@
import sys, os
from twisted.python import usage
+from twisted.python import filepath
+from plistlib import readPlist
+
from caladmin import commands
from caladmin import formatters
@@ -40,18 +43,55 @@
params = ()
optParameters = [
- ['format', 'f', 'plain', "Select an appropriate output formatter: %s" % (formatters.listFormatters())]
+ ['format', 'f', 'plain', ("Select an appropriate output formatter: "
+ "%s" % (formatters.listFormatters(),))]
]
+ def __init__(self):
+ usage.Options.__init__(self)
+
+ self.config = readPlist('/etc/caldavd/caldavd.plist.default')
+
+ self['config'] = '/etc/caldavd/caldavd.plist'
+
+ self.config.update(readPlist(self['config']))
+
+ self['root'] = self.config['DocumentRoot']
+ self.opt_root(self['root'])
+
+ def opt_config(self, path):
+ """Path to the caldavd.plist config file
+ [default: %s]
+ """ % (self['config'],)
+
+ self.config = readPlist(self['config'])
+
+ def opt_root(self, path):
+ """Path to the root of the calendar server document store.
+ [default: %s]
+ """ % (self['root'],)
+
+ self['root'] = filepath.FilePath(path)
+
def parseArgs(self, *rest):
self.params += rest
- def subCommands(self):
- return commands.genSubCommandsDef()
+ def parseOptions(self, options=None):
+ if not options:
+ options = ['--help']
- subCommands = property(subCommands)
+ if options == ['--help']:
+ self.subCommands = commands.genSubCommandsDef()
+
+ usage.Options.parseOptions(self, options)
def postOptions(self):
+ if self.recursing:
+ return
+
+ self.calendarCollection = self['root'].child('calendars')
+ self.principalCollection = self['root'].child('principals')
+
lf = formatters.listFormatters()
lf.sort()
@@ -61,12 +101,25 @@
raise usage.UsageError("Please specify a valid formatter: %s" % (
', '.join(lf)))
+ sc = commands.listCommands()
+ sc.sort()
+
+ self.subCommands = commands.genSubCommandsDef()
+
+ self.recursing = 1
+
+ self.parseOptions(self.params)
+
+ if self.subCommand not in sc:
+ raise usage.UsageError("Please select one of: %s" % (
+ ', '.join(sc)))
+
def run():
config = AdminOptions()
try:
- config.parseOptions()
+ config.parseOptions(sys.argv[1:])
except usage.UsageError, ue:
print config
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20061121/289b69d4/attachment.html
More information about the calendarserver-changes
mailing list