Package ZenWidgets :: Package browser :: Module Portlets
[hide private]
[frames] | no frames]

Source Code for Module ZenWidgets.browser.Portlets

  1  ########################################################################### 
  2  # 
  3  # This program is part of Zenoss Core, an open source monitoring platform. 
  4  # Copyright (C) 2007, Zenoss Inc. 
  5  # 
  6  # This program is free software; you can redistribute it and/or modify it 
  7  # under the terms of the GNU General Public License version 2 as published by 
  8  # the Free Software Foundation. 
  9  # 
 10  # For complete information please visit: http://www.zenoss.com/oss/ 
 11  # 
 12  ########################################################################### 
 13   
 14  import re 
 15  import simplejson 
 16   
 17  from Products.Five.browser import BrowserView 
 18  from Products.AdvancedQuery import Eq, Or 
 19   
 20  from Products.ZenUtils.Utils import relative_time 
 21  from Products.ZenUtils.json import json 
 22  from Products.ZenUtils.Utils import formreq, extractPostContent 
 23  from Products.ZenWidgets import messaging 
 24  from Products.ZenModel.ZenossSecurity import * 
 25  from Products.ZenEvents.browser.EventPillsAndSummaries import \ 
 26                                     getDashboardObjectsEventSummary, \ 
 27                                     ObjectsEventSummary,    \ 
 28                                     getEventPillME 
 29   
 30   
31 -class TopLevelOrganizerPortletView(ObjectsEventSummary):
32 """ 33 Return JSON event summaries for a root organizer. 34 """ 35 @formreq
36 - def __call__(self, dataRoot):
37 self.dataRoot = dataRoot 38 return super(TopLevelOrganizerPortletView, self).__call__()
39
40 - def _getObs(self):
41 return self.context.dmd.getDmdRoot(self.dataRoot).children()
42 43
44 -class ProductionStatePortletView(BrowserView):
45 """ 46 Return a map of device to production state in a format suitable for a 47 YUI data table. 48 """ 49 @formreq
50 - def __call__(self, *args, **kwargs):
51 return self.getDevProdStateJSON(*args, **kwargs)
52 53 @json
54 - def getDevProdStateJSON(self, prodStates=['Maintenance']):
55 """ 56 Return a map of device to production state in a format suitable for a 57 YUI data table. 58 59 @return: A JSON representation of a dictionary describing devices 60 @rtype: "{ 61 'columns':['Device', 'Prod State'], 62 'data':[ 63 {'Device':'<a href=/>', 'Prod State':'Production'}, 64 {'Device':'<a href=/>', 'Prod State':'Maintenance'}, 65 ]}" 66 """ 67 devroot = self.context.dmd.Devices 68 if type(prodStates)==type(''): 69 prodStates = [prodStates] 70 orderby, orderdir = 'id', 'asc' 71 catalog = getattr(devroot, devroot.default_catalog) 72 queries = [] 73 for state in prodStates: 74 queries.append(Eq('getProdState', state)) 75 query = Or(*queries) 76 objects = catalog.evalAdvancedQuery(query, ((orderby, orderdir),)) 77 devs = (x.getObject() for x in objects) 78 mydict = {'columns':['Device', 'Prod State'], 'data':[]} 79 for dev in devs: 80 if not self.context.checkRemotePerm(ZEN_VIEW, dev): continue 81 mydict['data'].append({ 82 'Device' : dev.getPrettyLink(), 83 'Prod State' : dev.getProdState() 84 }) 85 mydict['data'] = mydict['data'][:100] 86 return mydict
87 88
89 -class WatchListPortletView(BrowserView):
90 """ 91 Accepts a list of paths to Zope objects which it then attempts to resolve. 92 If no list of paths is given, it will try to read them from the POST data 93 of the REQUEST object. 94 95 @param entities: A list of paths that should be resolved into objects 96 and passed to L{getDashboardObjectsEventSummaryJSON}. 97 @type entities: list 98 @return: A JSON-formatted string representation of the columns and rows 99 of the table 100 @rtype: string 101 """ 102 @formreq
103 - def __call__(self, *args, **kwargs):
104 return self.getEntityListEventSummary(*args, **kwargs)
105 106 @json
107 - def getEntityListEventSummary(self, entities=None):
108 if entities is None: 109 entities = [] 110 elif isinstance(entities, basestring): 111 entities = [entities] 112 def getob(e): 113 e = str(e) 114 try: 115 if not e.startswith('/zport/dmd'): 116 bigdev = '/zport/dmd' + e 117 obj = self.context.dmd.unrestrictedTraverse(bigdev) 118 except (AttributeError, KeyError): 119 obj = self.context.dmd.Devices.findDevice(e) 120 if self.context.has_permission("View", obj): return obj
121 entities = filter(lambda x:x is not None, map(getob, entities)) 122 return getDashboardObjectsEventSummary( 123 self.context.dmd.ZenEventManager, entities)
124 125
126 -class DeviceIssuesPortletView(BrowserView):
127 """ 128 A list of devices with issues. 129 """
130 - def __call__(self):
131 return self.getDeviceIssuesJSON()
132 133 @json
134 - def getDeviceIssuesJSON(self):
135 """ 136 Get devices with issues in a form suitable for a portlet on the 137 dashboard. 138 139 @return: A JSON representation of a dictionary describing devices 140 @rtype: "{ 141 'columns':['Device', "Events'], 142 'data':[ 143 {'Device':'<a href=/>', 'Events':'<div/>'}, 144 {'Device':'<a href=/>', 'Events':'<div/>'}, 145 ]}" 146 """ 147 mydict = {'columns':[], 'data':[]} 148 mydict['columns'] = ['Device', 'Events'] 149 deviceinfo = self.getDeviceDashboard() 150 for alink, pill in deviceinfo: 151 mydict['data'].append({'Device':alink, 152 'Events':pill}) 153 return mydict
154
155 - def getDeviceDashboard(self):
156 """return device info for bad device to dashboard""" 157 zem = self.context.dmd.ZenEventManager 158 devices = [d[0] for d in zem.getDeviceIssues( 159 severity=4, state=1)] 160 devdata = [] 161 devclass = zem.getDmdRoot("Devices") 162 getcolor = re.compile(r'class=\"evpill-(.*?)\"', re.S|re.I|re.M).search 163 colors = "red orange yellow blue grey green".split() 164 def pillcompare(a,b): 165 a, b = map(lambda x:getcolor(x[1]), (a, b)) 166 def getindex(x): 167 try: 168 color = x.groups()[0] 169 smallcolor = x.groups()[0].replace('-acked','') 170 isacked = 'acked' in color 171 index = colors.index(x.groups()[0].replace('-acked','')) 172 if isacked: index += .5 173 return index 174 except: return 5
175 a, b = map(getindex, (a, b)) 176 return cmp(a, b)
177 for devname in devices: 178 dev = devclass.findDevice(devname) 179 if dev and dev.id == devname: 180 if (not zem.checkRemotePerm(ZEN_VIEW, dev) 181 or dev.productionState < zem.prodStateDashboardThresh 182 or dev.priority < zem.priorityDashboardThresh): 183 continue 184 alink = dev.getPrettyLink() 185 try: 186 pill = getEventPillME(zem, dev)[0] 187 except IndexError: 188 continue 189 evts = [alink,pill] 190 devdata.append(evts) 191 devdata.sort(pillcompare) 192 return devdata[:100] 193 194
195 -class HeartbeatPortletView(BrowserView):
196 """ 197 Heartbeat issues in YUI table form, for the dashboard portlet 198 """
199 - def __call__(self):
200 return self.getHeartbeatIssuesJSON()
201 202 @json
203 - def getHeartbeatIssuesJSON(self):
204 """ 205 Get heartbeat issues in a form suitable for a portlet on the dashboard. 206 207 @return: A JSON representation of a dictionary describing heartbeats 208 @rtype: "{ 209 'columns':['Device', 'Daemon', 'Seconds'], 210 'data':[ 211 {'Device':'<a href=/>', 'Daemon':'zenhub', 'Seconds':10} 212 ]}" 213 """ 214 mydict = {'columns':[], 'data':[]} 215 mydict['columns'] = ['Device', 'Daemon', 'Seconds'] 216 heartbeats = self.context.dmd.ZenEventManager.getHeartbeat() 217 for Device, Daemon, Seconds, dummy in heartbeats: 218 mydict['data'].append({'Device':Device, 219 'Daemon':Daemon, 'Seconds':Seconds}) 220 return mydict
221 222
223 -class UserMessagesPortletView(BrowserView):
224 """ 225 User messages in YUI table form, for the dashboard portlet. 226 """ 227 @json
228 - def __call__(self):
229 """ 230 Get heartbeat issues in a form suitable for a portlet on the dashboard. 231 232 @return: A JSON representation of a dictionary describing heartbeats 233 @rtype: "{ 234 'columns':['Device', 'Daemon', 'Seconds'], 235 'data':[ 236 {'Device':'<a href=/>', 'Daemon':'zenhub', 'Seconds':10} 237 ]}" 238 """ 239 ICONS = ['/zport/dmd/img/agt_action_success-32.png', 240 '/zport/dmd/img/messagebox_warning-32.png', 241 '/zport/dmd/img/agt_stop-32.png'] 242 msgbox = messaging.IUserMessages(self.context) 243 msgs = msgbox.get_messages() 244 cols = ['Message'] 245 res = [] 246 for msg in msgs: 247 res.append(dict( 248 title = msg.title, 249 imgpath = ICONS[msg.priority], 250 body = msg.body, 251 ago = relative_time(msg.timestamp), 252 deletelink = msg.absolute_url_path() + '/delMsg' 253 )) 254 res.reverse() 255 return { 'columns': cols, 'data': res }
256