Package flumotion :: Package common :: Module messages
[hide private]

Source Code for Module flumotion.common.messages

  1  # -*- Mode: Python; test-case-name: flumotion.test.test_common_messages -*- 
  2  # vi:si:et:sw=4:sts=4:ts=4 
  3  # 
  4  # Flumotion - a streaming media server 
  5  # Copyright (C) 2004,2005,2006,2007 Fluendo, S.L. (www.fluendo.com). 
  6  # All rights reserved. 
  7   
  8  # This file may be distributed and/or modified under the terms of 
  9  # the GNU General Public License version 2 as published by 
 10  # the Free Software Foundation. 
 11  # This file is distributed without any warranty; without even the implied 
 12  # warranty of merchantability or fitness for a particular purpose. 
 13  # See "LICENSE.GPL" in the source distribution for more information. 
 14   
 15  # Licensees having purchased or holding a valid Flumotion Advanced 
 16  # Streaming Server license may use this file in accordance with the 
 17  # Flumotion Advanced Streaming Server Commercial License Agreement. 
 18  # See "LICENSE.Flumotion" in the source distribution for more information. 
 19   
 20  # Headers in this file shall remain intact. 
 21   
 22  """serializable translatable messages. 
 23  support for serializable translatable messages from component/manager to admin 
 24  """ 
 25   
 26  import time 
 27   
 28  from twisted.spread import pb 
 29   
 30  from flumotion.common import log 
 31  from flumotion.configure import configure 
 32  from flumotion.common.i18n import FancyEqMixin, Translatable 
 33   
 34  __version__ = "$Rev: 6993 $" 
 35   
 36  (ERROR, 
 37   WARNING, 
 38   INFO) = range(1, 4) 
 39   
 40   
 41  # NOTE: same caveats apply for FancyEqMixin as above 
 42  # this might be a little heavy; we could consider only comparing 
 43  # on id, once we verify that all id's are unique 
 44   
45 -class Message(pb.Copyable, pb.RemoteCopy, FancyEqMixin):
46 """ 47 I am a message to be shown in a UI. 48 49 Projects should subclass this base class to provide default project 50 and version class attributes. 51 52 @ivar section: name of the section in which the message is described. 53 @type section: str 54 @ivar anchor: name of the anchor in which the message is described. 55 @type anchor: str 56 @ivar description: the link text to show 57 @type description: L{flumotion.common.messages.Translatable} 58 """ 59 project = configure.PACKAGE 60 version = configure.version 61 62 # these properties allow linking to the documentation 63 section = None 64 anchor = None 65 description = None 66 67 compareAttributes = ["level", "translatables", "debug", "mid", "priority", 68 "timestamp"] 69 70 # F0.8: remove id= in favor of mid=
71 - def __init__(self, level, translatable, debug=None, id=None, priority=50, 72 timestamp=None, mid=None):
73 """ 74 Create a new message. 75 76 The id identifies this kind of message, and serves two purposes. 77 78 The first purpose is to serve as a key by which a kind of 79 message might be removed from a set of messages. For example, a 80 firewire component detecting that a cable has been plugged in 81 will remove any message that the cable is unplugged. 82 83 Secondly it serves so that the message viewers that watch the 84 'current state' of some object only see the latest message of a 85 given type. For example when messages are stored in persistent 86 state objects that can be transferred over the network, it 87 becomes inefficient to store the whole history of status 88 messages. Message stores can keep only the latest message of a 89 given ID. 90 91 @param level: ERROR, WARNING or INFO 92 @param translatable: a translatable possibly with markup for 93 linking to documentation or running commands. 94 @param debug: further, untranslated, debug information, not 95 always shown 96 @param priority: priority compared to other messages of the same 97 level 98 @param timestamp: time since epoch at which the message was 99 generated, in seconds. 100 @param mid: A unique id for this kind of message, as 101 discussed above. If not given, will be 102 generated from the contents of the 103 translatable. 104 """ 105 self.level = level 106 self.translatables = [] 107 self.debug = debug 108 if id: 109 import warnings 110 warnings.warn('Please use the mid kwarg instead', 111 DeprecationWarning, stacklevel=3) 112 mid = id 113 114 # FIXME: untranslated is a really poor choice of id 115 self.id = mid or translatable.untranslated() 116 self.priority = priority 117 self.timestamp = timestamp or time.time() 118 # -1 is in __init__, -2 is in the subclass __init__, -3 is in the caller 119 log.doLog(log.DEBUG, None, 'messages', 120 'creating message %r', self, where=-3) 121 self.add(translatable)
122
123 - def __repr__(self):
124 return '<Message %r at %r>' % (self.id, id(self))
125
126 - def add(self, translatable):
127 if not isinstance(translatable, Translatable): 128 raise ValueError('%r is not Translatable' % translatable) 129 self.translatables.append(translatable) 130 log.doLog(log.DEBUG, None, 'messages', 131 'message %r: adding %r', (id(self), translatable.untranslated()), 132 where=-2)
133 134 pb.setUnjellyableForClass(Message, Message) 135 136 # these are implemented as factory functions instead of classes because 137 # properly proxying to the correct subclass is hard with Copyable/RemoteCopy
138 -def Error(*args, **kwargs):
139 """ 140 Create a L{Message} at ERROR level, indicating a failure that needs 141 intervention to be resolved. 142 """ 143 return Message(ERROR, *args, **kwargs)
144 145 # FIXME: figure out a way to not be shadowing the Warning builtin without 146 # breaking all other code 147 __pychecker__ = 'no-shadowbuiltin'
148 -def Warning(*args, **kwargs):
149 """ 150 Create a L{Message} at WARNING level, indicating a potential problem. 151 """ 152 return Message(WARNING, *args, **kwargs)
153 __pychecker__ = '' 154
155 -def Info(*args, **kwargs):
156 """ 157 Create a L{Message} at INFO level. 158 """ 159 return Message(INFO, *args, **kwargs)
160
161 -class Result(pb.Copyable, pb.RemoteCopy):
162 """ 163 I am used in worker checks to return a result. 164 165 @ivar value: the result value of the check 166 @ivar failed: whether or not the check failed. Typically triggered 167 by adding an ERROR message to the result. 168 @ivar messages: list of messages 169 @type messages: list of L{Message} 170 """
171 - def __init__(self):
172 self.messages = [] 173 self.value = None 174 self.failed = False
175
176 - def succeed(self, value):
177 """ 178 Make the result be successful, setting the given result value. 179 """ 180 self.value = value
181
182 - def add(self, message):
183 """ 184 Add a message to the result. 185 186 @type message: L{Message} 187 """ 188 self.messages.append(message) 189 if message.level == ERROR: 190 self.failed = True 191 self.value = None
192 pb.setUnjellyableForClass(Result, Result) 193