Back to index

moin  1.9.0~rc2
SystemInfo.py
Go to the documentation of this file.
00001 # -*- coding: iso-8859-1 -*-
00002 """
00003     MoinMoin - SystemInfo Macro
00004 
00005     This macro shows some info about your wiki, wiki software and your system.
00006 
00007     @copyright: 2006-2008 MoinMoin:ThomasWaldmann,
00008                 2007 MoinMoin:ReimarBauer
00009     @license: GNU GPL, see COPYING for details.
00010 """
00011 
00012 Dependencies = ['pages']
00013 
00014 import sys, os
00015 from StringIO import StringIO
00016 
00017 from MoinMoin import wikiutil, version
00018 from MoinMoin import action, macro, parser
00019 from MoinMoin.logfile import editlog, eventlog
00020 from MoinMoin.Page import Page
00021 
00022 class SystemInfo:
00023     def __init__(self, macro):
00024         self.macro = macro
00025         self.request = macro.request
00026         self.formatter = macro.formatter
00027 
00028     def formatInReadableUnits(self, size):
00029         size = float(size)
00030         unit = u' Byte'
00031         if size > 9999:
00032             unit = u' KiB'
00033             size /= 1024
00034         if size > 9999:
00035             unit = u' MiB'
00036             size /= 1024
00037         if size > 9999:
00038             unit = u' GiB'
00039             size /= 1024
00040         return u"%.1f %s" % (size, unit)
00041 
00042     def getDirectorySize(self, path):
00043         try:
00044             dirsize = 0
00045             for root, dummy, files in os.walk(path):
00046                 dirsize += sum([os.path.getsize(os.path.join(root, name)) for name in files])
00047         except EnvironmentError:
00048             dirsize = -1
00049         return dirsize
00050 
00051     def render(self):
00052         _ = self.request.getText
00053         return self.formatter.rawHTML(self.getInfo())
00054 
00055     def getInfo(self):
00056         _ = self.request.getText
00057         request = self.request
00058 
00059         buf = StringIO()
00060 
00061         row = lambda label, value, buf=buf: buf.write(u'<dt>%s</dt><dd>%s</dd>' % (label, value))
00062 
00063         buf.write(u'<dl>')
00064         row(_('Python Version'), sys.version)
00065         row(_('MoinMoin Version'), _('Release %s [Revision %s]') % (version.release, version.revision))
00066 
00067         if not request.user.valid:
00068             # for an anonymous user it ends here.
00069             buf.write(u'</dl>')
00070             return buf.getvalue()
00071 
00072         if request.user.isSuperUser():
00073             # superuser gets all page dependent stuff only
00074             try:
00075                 import Ft
00076                 ftversion = Ft.__version__
00077             except ImportError:
00078                 ftversion = None
00079             except AttributeError:
00080                 ftversion = 'N/A'
00081 
00082             if ftversion:
00083                 row(_('4Suite Version'), ftversion)
00084 
00085             # TODO add python-xml check and display it
00086 
00087             # Get the full pagelist of the wiki
00088             pagelist = request.rootpage.getPageList(user='')
00089             systemPages = []
00090             totalsize = 0
00091             for page in pagelist:
00092                 if wikiutil.isSystemPage(request, page):
00093                     systemPages.append(page)
00094                 totalsize += Page(request, page).size()
00095 
00096             row(_('Number of pages'), str(len(pagelist)-len(systemPages)))
00097             row(_('Number of system pages'), str(len(systemPages)))
00098 
00099             row(_('Accumulated page sizes'), self.formatInReadableUnits(totalsize))
00100             data_dir = request.cfg.data_dir
00101             row(_('Disk usage of %(data_dir)s/pages/') % {'data_dir': data_dir},
00102                 self.formatInReadableUnits(self.getDirectorySize(os.path.join(data_dir, 'pages'))))
00103             row(_('Disk usage of %(data_dir)s/') % {'data_dir': data_dir},
00104             self.formatInReadableUnits(self.getDirectorySize(data_dir)))
00105 
00106             edlog = editlog.EditLog(request)
00107             row(_('Entries in edit log'), "%s (%s)" % (edlog.lines(), self.formatInReadableUnits(edlog.size())))
00108 
00109             # This puts a heavy load on the server when the log is large
00110             eventlogger = eventlog.EventLog(request)
00111             row('Event log', self.formatInReadableUnits(eventlogger.size()))
00112 
00113         nonestr = _("NONE")
00114         # a valid user gets info about all installed extensions
00115         row(_('Global extension macros'), ', '.join(macro.modules) or nonestr)
00116         row(_('Local extension macros'),
00117             ', '.join(wikiutil.wikiPlugins('macro', self.macro.cfg)) or nonestr)
00118 
00119         glob_actions = [x for x in action.modules
00120                         if not x in request.cfg.actions_excluded]
00121         row(_('Global extension actions'), ', '.join(glob_actions) or nonestr)
00122         loc_actions = [x for x in wikiutil.wikiPlugins('action', self.macro.cfg)
00123                        if not x in request.cfg.actions_excluded]
00124         row(_('Local extension actions'), ', '.join(loc_actions) or nonestr)
00125 
00126         row(_('Global parsers'), ', '.join(parser.modules) or nonestr)
00127         row(_('Local extension parsers'),
00128             ', '.join(wikiutil.wikiPlugins('parser', self.macro.cfg)) or nonestr)
00129 
00130         try:
00131             import xapian
00132             xapVersion = 'Xapian %s' % xapian.version_string()
00133         except ImportError:
00134             xapian = None
00135             xapVersion = _('Xapian and/or Python Xapian bindings not installed')
00136 
00137         xapian_enabled = request.cfg.xapian_search
00138         xapState = (_('Disabled'), _('Enabled'))
00139         xapRow = '%s, %s' % (xapState[xapian_enabled], xapVersion)
00140 
00141         if xapian and xapian_enabled:
00142             from MoinMoin.search.Xapian.indexing import XapianIndex
00143             idx = XapianIndex(request)
00144             idxState = (_('index unavailable'), _('index available'))
00145             idx_exists = idx.exists()
00146             xapRow += ', %s' % idxState[idx_exists]
00147             if idx_exists:
00148                 xapRow += ', %s' % (_('last modified: %s') %
00149                     request.user.getFormattedDateTime(idx.mtime()))
00150 
00151         row(_('Xapian search'), xapRow)
00152 
00153         if xapian and xapian_enabled:
00154             stems = xapian.Stem.get_available_languages()
00155             row(_('Stemming for Xapian'), xapState[request.cfg.xapian_stemming] +
00156                 " (%s)" % (stems or nonestr))
00157 
00158         try:
00159             from threading import activeCount
00160             t_count = activeCount()
00161         except ImportError:
00162             t_count = None
00163 
00164         row(_('Active threads'), t_count or _('N/A'))
00165         buf.write(u'</dl>')
00166 
00167         return buf.getvalue()
00168 
00169 def macro_SystemInfo(macro):
00170     if macro.request.isSpiderAgent: # reduce bot cpu usage
00171         return ''
00172     return SystemInfo(macro).render()
00173