1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 """serializable translatable messages.
19 support for serializable translatable messages from component/manager to admin
20 """
21
22 import time
23
24 from twisted.spread import pb
25
26 from flumotion.common import log
27 from flumotion.configure import configure
28 from flumotion.common.i18n import FancyEqMixin, Translatable
29 from flumotion.common.i18n import *
30
31 __version__ = "$Rev$"
32
33 (ERROR,
34 WARNING,
35 INFO) = range(1, 4)
36
37
38
39
40
41
42
43 -class Message(pb.Copyable, pb.RemoteCopy, FancyEqMixin):
44 """
45 I am a message to be shown in a UI.
46
47 Projects should subclass this base class to provide default project
48 and version class attributes.
49
50 @ivar section: name of the section in which the message is described.
51 @type section: str
52 @ivar anchor: name of the anchor in which the message is described.
53 @type anchor: str
54 @ivar description: the link text to show
55 @type description: L{flumotion.common.messages.Translatable}
56 """
57 project = configure.PACKAGE
58 version = configure.version
59
60
61 section = None
62 anchor = None
63 description = None
64
65 compareAttributes = ["level", "translatables", "debug", "mid", "priority",
66 "timestamp"]
67
68 - def __init__(self, level, translatable, debug=None, mid=None, priority=50,
69 timestamp=None):
70 """
71 Create a new message.
72
73 The mid identifies this kind of message, and serves two purposes.
74
75 The first purpose is to serve as a key by which a kind of
76 message might be removed from a set of messages. For example, a
77 firewire component detecting that a cable has been plugged in
78 will remove any message that the cable is unplugged.
79
80 Secondly it serves so that the message viewers that watch the
81 'current state' of some object only see the latest message of a
82 given type. For example when messages are stored in persistent
83 state objects that can be transferred over the network, it
84 becomes inefficient to store the whole history of status
85 messages. Message stores can keep only the latest message of a
86 given ID.
87
88 @param level: ERROR, WARNING or INFO
89 @param translatable: a translatable possibly with markup for
90 linking to documentation or running commands.
91 @param debug: further, untranslated, debug information, not
92 always shown
93 @param priority: priority compared to other messages of the same
94 level
95 @param timestamp: time since epoch at which the message was
96 generated, in seconds.
97 @param mid: A unique id for this kind of message, as
98 discussed above. If not given, will be
99 generated from the contents of the
100 translatable.
101 """
102 self.level = level
103 self.translatables = []
104 self.debug = debug
105
106
107 self.id = mid or translatable.untranslated()
108 self.priority = priority
109 self.timestamp = timestamp or time.time()
110
111
112 log.doLog(log.DEBUG, None, 'messages',
113 'creating message %r', self, where=-3)
114 log.doLog(log.DEBUG, None, 'messages',
115 'message debug %s', debug)
116 self.add(translatable)
117
119 return '<Message %r at %r>' % (self.id, id(self))
120
121 - def add(self, translatable):
122 if not isinstance(translatable, Translatable):
123 raise ValueError('%r is not Translatable' % translatable)
124 self.translatables.append(translatable)
125 log.doLog(log.DEBUG, None, 'messages',
126 'message %r: adding %r', (id(self), translatable.untranslated()),
127 where=-2)
128
130 """Get the timestamp for the message
131 @returns: the timestamp or None
132 @rtype: int
133 """
134
135 return getattr(self, 'timestamp', None)
136
138 """Get the description for the message
139 @returns: the description or None
140 @rtype: str
141 """
142 return getattr(self, 'description', None)
143
144 pb.setUnjellyableForClass(Message, Message)
145
146
147
148
149
150 -def Error(*args, **kwargs):
151 """
152 Create a L{Message} at ERROR level, indicating a failure that needs
153 intervention to be resolved.
154 """
155 return Message(ERROR, *args, **kwargs)
156
157
158
159 __pychecker__ = 'no-shadowbuiltin'
160
161
163 """
164 Create a L{Message} at WARNING level, indicating a potential problem.
165 """
166 return Message(WARNING, *args, **kwargs)
167 __pychecker__ = ''
168
169
170 -def Info(*args, **kwargs):
171 """
172 Create a L{Message} at INFO level.
173 """
174 return Message(INFO, *args, **kwargs)
175
176
177 -class Result(pb.Copyable, pb.RemoteCopy):
178 """
179 I am used in worker checks to return a result.
180
181 @ivar value: the result value of the check
182 @ivar failed: whether or not the check failed. Typically triggered
183 by adding an ERROR message to the result.
184 @ivar messages: list of messages
185 @type messages: list of L{Message}
186 """
187
189 self.messages = []
190 self.value = None
191 self.failed = False
192
194 """
195 Make the result be successful, setting the given result value.
196 """
197 self.value = value
198
199 - def add(self, message):
200 """
201 Add a message to the result.
202
203 @type message: L{Message}
204 """
205 self.messages.append(message)
206 if message.level == ERROR:
207 self.failed = True
208 self.value = None
209 pb.setUnjellyableForClass(Result, Result)
210