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
34 __version__ = "$Rev: 6993 $"
35
36 (ERROR,
37 WARNING,
38 INFO) = range(1, 4)
39
40
41
42
43
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
63 section = None
64 anchor = None
65 description = None
66
67 compareAttributes = ["level", "translatables", "debug", "mid", "priority",
68 "timestamp"]
69
70
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
115 self.id = mid or translatable.untranslated()
116 self.priority = priority
117 self.timestamp = timestamp or time.time()
118
119 log.doLog(log.DEBUG, None, 'messages',
120 'creating message %r', self, where=-3)
121 self.add(translatable)
122
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
137
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
146
147 __pychecker__ = 'no-shadowbuiltin'
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 """
172 self.messages = []
173 self.value = None
174 self.failed = False
175
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