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