diff --git a/browser/runtimeinfo.py b/browser/runtimeinfo.py new file mode 100644 index 0000000..d5ba0dc --- /dev/null +++ b/browser/runtimeinfo.py @@ -0,0 +1,69 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Define runtime information view component for Application Control + +$Id$ +""" +from zope.app.applicationcontrol.interfaces import IRuntimeInfo + +from zope.app.i18n import ZopeMessageIDFactory as _ + +class RuntimeInfoView(object): + + def runtimeInfo(self): + formatted = {} # will contain formatted runtime information + + try: + runtime_info = IRuntimeInfo(self.context) + formatted['ZopeVersion'] = runtime_info.getZopeVersion() + formatted['PythonVersion'] = runtime_info.getPythonVersion() + formatted['PythonPath'] = runtime_info.getPythonPath() + formatted['SystemPlatform'] = runtime_info.getSystemPlatform() + formatted['PreferredEncoding'] = runtime_info.getPreferredEncoding() + formatted['FileSystemEncoding'] = \ + runtime_info.getFileSystemEncoding() + formatted['CommandLine'] = runtime_info.getCommandLine() + formatted['ProcessId'] = runtime_info.getProcessId() + + # make a unix "uptime" uptime format + uptime = long(runtime_info.getUptime()) + minutes, seconds = divmod(uptime, 60) + hours, minutes = divmod(minutes, 60) + days, hours = divmod(hours, 24) + + uptime = _('${days} day(s) ${hours}:${minutes}:${seconds}') + uptime.mapping = {'days': '%d' %days, + 'hours': '%02d' %hours, + 'minutes': '%02d' %minutes, + 'seconds': '%02d' %seconds} + + formatted['Uptime'] = uptime + + except (TypeError, UnicodeError): + # We avoid having errors in the ApplicationController, + # because all those things need to stay accessible. + na = _("n/a") + formatted['ZopeVersion'] = na + formatted['PythonVersion'] = na + formatted['PythonPath'] = (na,) + formatted['SystemPlatform'] = na + formatted['PreferredEncoding'] = na + formatted['FileSystemEncoding'] = na + formatted['CommandLine'] = na + formatted['ProcessId'] = na + formatted['Uptime'] = na + formatted['Hint'] = _("Could not retrieve runtime information.") + + return formatted + diff --git a/browser/servercontrol.py b/browser/servercontrol.py new file mode 100644 index 0000000..72c6ad9 --- /dev/null +++ b/browser/servercontrol.py @@ -0,0 +1,35 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Server Control View + +$Id$ +""" +from zope.app import zapi +from zope.app.applicationcontrol.interfaces import IServerControl + +from zope.app.i18n import ZopeMessageIDFactory as _ + +class ServerControlView(object): + + def serverControl(self): + return zapi.getUtility(IServerControl) + + def action(self, time=0): + """Do the shutdown/restart!""" + if 'restart' in self.request: + return (self.serverControl().restart(time) + or _(u"You restarted the server.")) + elif 'shutdown' in self.request: + return (self.serverControl().shutdown(time) + or _("You shut down the server.")) diff --git a/browser/translationdomaincontrol.py b/browser/translationdomaincontrol.py new file mode 100644 index 0000000..fc595f8 --- /dev/null +++ b/browser/translationdomaincontrol.py @@ -0,0 +1,51 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +"""Server Control View + +$Id$ +""" +from zope.i18n.interfaces import ITranslationDomain +from zope.app import zapi +from zope.app.i18n import ZopeMessageIDFactory as _ + +class TranslationDomainControlView(object): + + def getCatalogsInfo(self): + info = [] + for name, domain in zapi.getUtilitiesFor(ITranslationDomain): + if not hasattr(domain, 'getCatalogsInfo'): + continue + for language, fileNames in domain.getCatalogsInfo().items(): + info.append({'domain': name, + 'language': language, + 'fileNames': fileNames}) + return info + + + def reloadCatalogs(self): + """Do the reloading !""" + status = '' + + if 'RELOAD' in self.request: + language = self.request.get('language') + domain = self.request.get('domain') + + domain = zapi.getUtility(ITranslationDomain, domain) + for lang, fileNames in domain.getCatalogsInfo().items(): + if lang == language: + domain.reloadCatalogs(fileNames) + + status = _('Message Catalog successfully reloaded.') + + return status diff --git a/browser/zodbcontrol.py b/browser/zodbcontrol.py new file mode 100644 index 0000000..8dc3b3f --- /dev/null +++ b/browser/zodbcontrol.py @@ -0,0 +1,54 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +############################################################################## +""" Server Control View + +$Id$ +""" +from ZODB.FileStorage.FileStorage import FileStorageError +from zope.app.i18n import ZopeMessageIDFactory as _ + +class ZODBControlView(object): + + def getName(self): + """Get the database name.""" + return self.request.publication.db.getName() + + def getSize(self): + """Get the database size in a human readable format.""" + size = self.request.publication.db.getSize() + if size > 1024**2: + size_str = _("${size} MB") + size_str.mapping = {'size': "%.1f" %(float(size)/1024**2)} + elif size > 1024: + size_str = _("${size} kB") + size_str.mapping = {'size': "%.1f" %(float(size)/1024)} + else: + size_str = _("${size} Bytes") + size_str.mapping = {'size': "%i" %size} + + return size_str + + + def pack(self): + """Do the packing!""" + days = int(self.request.form.get('days', 0)) + status = '' + if 'PACK' in self.request: + try: + self.request.publication.db.pack(days=days) + status = _('ZODB successfully packed.') + except FileStorageError, err: + status = _(err) + + return status diff --git a/tests/test_runtimeinfo.py b/tests/test_runtimeinfo.py new file mode 100644 index 0000000..333df6e --- /dev/null +++ b/tests/test_runtimeinfo.py @@ -0,0 +1,129 @@ +############################################################################## +# +# Copyright (c) 2001, 2002 Zope Corporation and Contributors. +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +############################################################################## +"""Runtime Info Tests + +$Id$ +""" +import unittest +import os, sys, time + +try: + import locale +except ImportError: + locale = None + +from zope.component import getService +from zope.interface import implements +from zope.interface.verify import verifyObject +from zope.app.applicationcontrol.applicationcontrol import applicationController +from zope.app.applicationcontrol.interfaces import IRuntimeInfo, IZopeVersion +from zope.app.site.tests.placefulsetup import PlacefulSetup + +# seconds, time values may differ in order to be assumed equal +time_tolerance = 2 +stupid_version_string = "3085t0klvn93850voids" + +class TestZopeVersion(object): + """A fallback implementation for the ZopeVersion utility.""" + + implements(IZopeVersion) + + def getZopeVersion(self): + return stupid_version_string + +class Test(PlacefulSetup, unittest.TestCase): + + def _Test__new(self): + from zope.app.applicationcontrol.runtimeinfo import RuntimeInfo + return RuntimeInfo(applicationController) + + def _getPreferredEncoding(self): + if locale is not None: + try: + return locale.getpreferredencoding() + except locale.Error: + pass + return sys.getdefaultencoding() + + def _getFileSystemEncoding(self): + enc = sys.getfilesystemencoding() + if enc is None: + enc = self._getPreferredEncoding() + return enc + + def testIRuntimeInfoVerify(self): + verifyObject(IRuntimeInfo, self._Test__new()) + + def test_PreferredEncoding(self): + runtime_info = self._Test__new() + enc = self._getPreferredEncoding() + self.assertEqual(runtime_info.getPreferredEncoding(), enc) + + def test_FileSystemEncoding(self): + runtime_info = self._Test__new() + enc = self._getFileSystemEncoding() + self.assertEqual(runtime_info.getFileSystemEncoding(), enc) + + def test_ZopeVersion(self): + runtime_info = self._Test__new() + + # we expect that there is no utility + self.assertEqual(runtime_info.getZopeVersion(), "") + + getService('Utilities').provideUtility(IZopeVersion, + TestZopeVersion()) + self.assertEqual(runtime_info.getZopeVersion(), + stupid_version_string) + def test_PythonVersion(self): + runtime_info = self._Test__new() + enc = self._getPreferredEncoding() + self.assertEqual(runtime_info.getPythonVersion(), + unicode(sys.version, enc)) + + def test_SystemPlatform(self): + runtime_info = self._Test__new() + test_platform = (sys.platform,) + if hasattr(os, "uname"): + test_platform = os.uname() + enc = self._getPreferredEncoding() + self.assertEqual(runtime_info.getSystemPlatform(), + unicode(" ".join(test_platform), enc)) + + def test_CommandLine(self): + runtime_info = self._Test__new() + self.assertEqual(runtime_info.getCommandLine(), " ".join(sys.argv)) + + def test_ProcessId(self): + runtime_info = self._Test__new() + self.assertEqual(runtime_info.getProcessId(), os.getpid()) + + def test_Uptime(self): + runtime_info = self._Test__new() + # whats the uptime we expect? + + start_time = applicationController.getStartTime() + asserted_uptime = time.time() - start_time + + # get the uptime the current implementation calculates + test_uptime = runtime_info.getUptime() + + self.failUnless(abs(asserted_uptime - test_uptime) < time_tolerance) + + +def test_suite(): + return unittest.TestSuite(( + unittest.makeSuite(Test), + )) + +if __name__ == '__main__': + unittest.main()