class LogEvents(YomboLibrary): """ Manages all notifications. """ def _init_(self): """ Setups up the basic framework. """ # We only cache the last few events, and only for certain time. self.notifications = ExpiringDict(max_len=100, max_age_seconds=600) # return self.init_deferred def _load_(self): self._LocalDB = self._Libraries['localdb'] self._checkExpiredLoop = LoopingCall(self.check_expired) self._checkExpiredLoop.start( self._Configs.get('notifications', 'check_expired', 30, False)) self.load_notifications() def _stop_(self): if self.init_deferred is not None and self.init_deferred.called is False: self.init_deferred.callback( 1) # if we don't check for this, we can't stop! def _clear_(self): """ Clear all devices. Should only be called by the loader module during a reconfiguration event. B{Do not call this function!} """ self.notifications.clear() def _reload_(self): self._clear_() self.load_notifications() def check_expired(self): """ Called by looping call to periodically purge expired notifications. :return: """ cur_time = int(time()) for id, notice in self.notifications.items(): print("cur : expired = %s : %s" % (cur_time, notice.expire)) if cur_time > notice.expire: print("deleting notice: %s" % notice.title) del self.notifications[id] self._LocalDB.delete_expired_notifications() def get(self, notification_requested): """ Performs the actual search. .. note:: Modules shouldn't use this function. Use the built in reference to find notification: `self._Notifications['8w3h4sa']` :raises YomboWarning: Raised when notifcation cannot be found. :param notification_requested: The input type ID or input type label to search for. :type notification_requested: string :return: A dict containing details about the notification :rtype: dict """ if notification_requested in self.notifications: return self.notifications[notification_requested] else: raise YomboWarning('Notification not found: %s' % notification_requested) def delete(self, notification_requested): """ Deletes a provided notification. :param notification_requested: :return: """ try: del self.notifications[notification_requested] except: pass self._LocalDB.delete_notification(notification_requested) @inlineCallbacks def load_notifications(self): """ Load the last few notifications into memory. """ notifications = yield self._LocalDB.get_notifications() for notice in notifications: notice = notice.__dict__ if notice['expire'] < int(time()): continue notice['meta'] = json.loads(notice['meta']) self.add_notice(notice, from_db=True) logger.debug("Done load_notifications: {notifications}", notifications=self.notifications) # self.init_deferred.callback(10) def add_notice(self, notice, from_db=False, persist=True, create_event=False): """ Add a new notice. :param notice: A dictionary containing notification details. :type record: dict :returns: Pointer to new notice. Only used during unittest """ print("adding notice1: %s" % notice) if 'id' not in notice: notice['id'] = random_string(length=16) if 'type' not in notice: notice['type'] = 'system' if 'priority' not in notice: notice['priority'] = 'normal' if 'source' not in notice: notice['source'] = '' if 'expire' not in notice: if 'timeout' in notice: notice['expire'] = int(time()) + notice['timeout'] else: notice['expire'] = int(time()) + 3600 else: if notice['expire'] > int(time()): YomboWarning( "New notification is set to expire before current time.") if 'created_at' not in notice: notice['created_at'] = int(time()) if 'acknowledged' not in notice: notice['acknowledged'] = False else: if notice['acknowledged'] not in (True, False): YomboWarning( "New notification 'acknowledged' must be either True or False." ) if 'title' not in notice: raise YomboWarning("New notification requires a title.") if 'message' not in notice: raise YomboWarning("New notification requires a message.") if 'meta' not in notice: notice['meta'] = {} logger.debug("notice: {notice}", notice=notice) if from_db is False: self._LocalDB.add_notification(notice) self.notifications.prepend(notice['id'], Notification(notice)) else: self.notifications[notice['id']] = Notification(notice) # self.notifications = OrderedDict(sorted(self.notifications.items(), key=lambda x: x[1]['created_at'])) pass return notice['id']