Blame view

product/ERP5/Tool/AlarmTool.py 6.84 KB
Sebastien Robin committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
##############################################################################
#
# Copyright (c) 2004 Nexedi SARL and Contributors. All Rights Reserved.
#                    Sebastien Robin <seb@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
##############################################################################

Jean-Paul Smets committed
29
import time
Jérome Perrin committed
30 31
import threading

Sebastien Robin committed
32
from AccessControl import ClassSecurityInfo
Jean-Paul Smets committed
33
from AccessControl.SecurityManagement import newSecurityManager
Sebastien Robin committed
34
from Globals import InitializeClass, DTMLFile, PersistentMapping
Jean-Paul Smets committed
35
from Products.ERP5Type.Core.Folder import Folder
Sebastien Robin committed
36 37 38 39 40
from Products.ERP5Type.Tool.BaseTool import BaseTool
from Products.ERP5Type import Permissions
from Products.ERP5 import _dtmldir
from DateTime import DateTime

Jérome Perrin committed
41
from zLOG import LOG, INFO
Sebastien Robin committed
42

Jean-Paul Smets committed
43 44 45
try:
  from Products.TimerService import getTimerService
except ImportError:
Jérome Perrin committed
46
  def getTimerService(self):
Jean-Paul Smets committed
47
    pass
Sebastien Robin committed
48

Jérome Perrin committed
49 50 51
last_tic = time.time()
last_tic_lock = threading.Lock()

Sebastien Robin committed
52 53
class AlarmTool(BaseTool):
  """
Aurel committed
54 55
    This tool manages alarms.

Vincent Pelletier committed
56
    It is used as a central managment point for all alarms.
Sebastien Robin committed
57

Vincent Pelletier committed
58 59
    Inside this tool we have a way to retrieve all reports comings
    from Alarms,...
Sebastien Robin committed
60 61 62 63 64 65 66 67 68 69 70 71 72 73
  """
  id = 'portal_alarms'
  meta_type = 'ERP5 Alarm Tool'
  portal_type = 'Alarm Tool'

  # Declarative Security
  security = ClassSecurityInfo()

  security.declareProtected( Permissions.ManagePortal, 'manage_overview' )
  manage_overview = DTMLFile( 'explainAlarmTool', _dtmldir )

  security.declareProtected( Permissions.ManagePortal , 'manageAlarmList' )
  manageAlarmList = DTMLFile( 'manageAlarmList', _dtmldir )

Aurel committed
74 75 76 77
  security.declareProtected( Permissions.ManagePortal , 'manageAlarmAdvanced' )
  manageAlarmAdvanced = DTMLFile( 'manageAlarmAdvanced', _dtmldir )


Sebastien Robin committed
78
  manage_options = ( ( { 'label'   : 'Overview'
Vincent Pelletier committed
79 80 81 82 83
                       , 'action'   : 'manage_overview'
                       }
                     , { 'label'   : 'All Alarms'
                       , 'action'   : 'manageAlarmList'
                       }
Aurel committed
84 85 86 87
                     , { 'label'   : 'Advanced'
                       , 'action'   : 'manageAlarmAdvanced'
                       }
                     ,
Vincent Pelletier committed
88 89 90
                     )
                     + Folder.manage_options
                   )
Sebastien Robin committed
91

Jérome Perrin committed
92
  _properties = ( {'id': 'interval', 'type': 'int', 'mode': 'w', }, )
Jean-Paul Smets committed
93
  interval = 60 # Default interval for alarms is 60 seconds
Vincent Pelletier committed
94

Sebastien Robin committed
95
  # API to manage alarms
Vincent Pelletier committed
96 97 98 99 100 101 102
  # Aim of this API:
  #-- see all alarms stored everywhere
  #-- defines global alarms
  #-- activate an alarm
  #-- see reports
  #-- see active alarms
  #-- retrieve all alarms
Sebastien Robin committed
103 104

  security.declareProtected(Permissions.ModifyPortalContent, 'getAlarmList')
Vincent Pelletier committed
105
  def getAlarmList(self, to_active = 0):
Sebastien Robin committed
106
    """
Vincent Pelletier committed
107
      We retrieve thanks to the catalog the full list of alarms
Sebastien Robin committed
108
    """
Jean-Paul Smets committed
109 110
    user = self.portal_catalog.getOwner()
    newSecurityManager(self.REQUEST, user)
Sebastien Robin committed
111
    if to_active:
Sebastien Robin committed
112
      now = DateTime()
Vincent Pelletier committed
113
      catalog_search = self.portal_catalog(
Sebastien Robin committed
114 115
        portal_type = self.getPortalAlarmTypeList(), 
        alarm_date={'query':now,'range':'ngt'}
Vincent Pelletier committed
116
      )
Sebastien Robin committed
117
      # check again the alarm date in case the alarm was not yet reindexed
Vincent Pelletier committed
118 119
      alarm_list = [x.getObject() for x in catalog_search \
          if x.getObject().getAlarmDate()<=now]
Sebastien Robin committed
120
    else:
Vincent Pelletier committed
121 122 123
      catalog_search = self.portal_catalog(
        portal_type = self.getPortalAlarmTypeList()
      )
Sebastien Robin committed
124
      alarm_list = [x.getObject() for x in catalog_search]
Sebastien Robin committed
125 126 127 128 129
    return alarm_list

  security.declareProtected(Permissions.ModifyPortalContent, 'tic')
  def tic(self):
    """
Vincent Pelletier committed
130 131
      We will look at all alarms and see if they should be activated,
      if so then we will activate them.
Sebastien Robin committed
132 133
    """
    current_date = DateTime()
Jean-Paul Smets committed
134 135 136 137
    for alarm in self.getAlarmList(to_active=1):
      if alarm:
        user = alarm.getOwner()
        newSecurityManager(self.REQUEST, user)
Aurel committed
138
        if alarm.isActive() or not alarm.isEnabled():
Jean-Paul Smets committed
139 140 141 142
          # do nothing if already active, or not enabled
          continue
        alarm.activate().activeSense()

Aurel committed
143 144
  security.declareProtected(Permissions.ManageProperties, 'isSubscribed')
  def isSubscribed(self):
Jérome Perrin committed
145 146 147 148 149 150
    """ return True, if we are subscribed to TimerService.
    Otherwise return False.
    """
    service = getTimerService(self)
    if not service:
      LOG('AlarmTool', INFO, 'TimerService not available')
Aurel committed
151 152
      return False

Jérome Perrin committed
153 154 155 156 157
    path = '/'.join(self.getPhysicalPath())
    if path in service.lisSubscriptions():
      return True
    return False

Jean-Paul Smets committed
158 159
  security.declareProtected(Permissions.ManageProperties, 'subscribe')
  def subscribe(self):
Vincent Pelletier committed
160 161 162
    """
      Subscribe to the global Timer Service.
    """
Jean-Paul Smets committed
163 164
    service = getTimerService(self)
    if not service:
Jérome Perrin committed
165 166
      LOG('AlarmTool', INFO, 'TimerService not available')
      return
Jean-Paul Smets committed
167 168 169 170 171
    service.subscribe(self)
    return "Subscribed to Timer Service"

  security.declareProtected(Permissions.ManageProperties, 'unsubscribe')
  def unsubscribe(self):
Vincent Pelletier committed
172 173 174
    """
      Unsubscribe from the global Timer Service.
    """
Jean-Paul Smets committed
175 176
    service = getTimerService(self)
    if not service:
Jérome Perrin committed
177 178
      LOG('AlarmTool', INFO, 'TimerService not available')
      return
Jean-Paul Smets committed
179 180 181 182 183
    service.unsubscribe(self)
    return "Usubscribed from Timer Service"

  def manage_beforeDelete(self, item, container):
    self.unsubscribe()
Jérome Perrin committed
184
    BaseTool.inheritedAttribute('manage_beforeDelete')(self, item, container)
Aurel committed
185

Jean-Paul Smets committed
186 187
  def manage_afterAdd(self, item, container):
    self.subscribe()
Jérome Perrin committed
188
    BaseTool.inheritedAttribute('manage_afterAdd')(self, item, container)
Aurel committed
189

Jérome Perrin committed
190
  security.declarePrivate('process_timer')
Aurel committed
191
  def process_timer(self, interval, tick, prev="", next=""):
Aurel committed
192
    """
Vincent Pelletier committed
193 194 195
      Call tic() every x seconds. x is defined in self.interval
      This method is called by TimerService in the interval given
      in zope.conf. The Default is every 5 seconds.
Jean-Paul Smets committed
196
    """
Jérome Perrin committed
197 198 199 200 201 202 203 204
    global last_tic
    last_tic_lock.acquire(1)
    try:
      if tick.timeTime() - last_tic >= self.interval:
        self.tic()
        last_tic = tick.timeTime()
    finally:
      last_tic_lock.release()
Sebastien Robin committed
205