Package flumotion :: Package component :: Package base :: Module eatersnode
[hide private]

Source Code for Module flumotion.component.base.eatersnode

  1  # -*- Mode: Python; test-case-name: flumotion.test.test_feedcomponent010 -*- 
  2  # vi:si:et:sw=4:sts=4:ts=4 
  3   
  4  # Flumotion - a streaming media server 
  5  # Copyright (C) 2004,2005,2006,2007,2008,2009 Fluendo, S.L. 
  6  # Copyright (C) 2010,2011 Flumotion Services, S.A. 
  7  # All rights reserved. 
  8  # 
  9  # This file may be distributed and/or modified under the terms of 
 10  # the GNU Lesser General Public License version 2.1 as published by 
 11  # the Free Software Foundation. 
 12  # This file is distributed without any warranty; without even the implied 
 13  # warranty of merchantability or fitness for a particular purpose. 
 14  # See "LICENSE.LGPL" in the source distribution for more information. 
 15  # 
 16  # Headers in this file shall remain intact. 
 17   
 18  """ 
 19  Eaters tab in the component UI 
 20  """ 
 21   
 22  import gettext 
 23  import os 
 24  import time 
 25   
 26  import gtk 
 27   
 28  from flumotion.common import format as formatting 
 29  from flumotion.common.i18n import gettexter 
 30  from flumotion.component.base.baseadminnode import BaseAdminGtkNode 
 31  from flumotion.component.base.statewatcher import StateWatcher 
 32   
 33  _ = gettext.gettext 
 34  __version__ = "$Rev$" 
 35  T_ = gettexter() 
 36   
 37   
38 -class EatersAdminGtkNode(BaseAdminGtkNode):
39 gladeFile = os.path.join('flumotion', 'component', 'base', 'eaters.glade') 40
41 - def __init__(self, state, admin):
42 BaseAdminGtkNode.__init__(self, state, admin, title=_("Eaters")) 43 # tree model is a model of id, uiState, StateWatcher 44 # tree model contains eaters 45 self.treemodel = None 46 self.treeview = None 47 self._selected = None # the watcher of the currently selected row 48 self.labels = {} 49 self._lastConnect = 0 50 self._lastDisconnect = 0
51
52 - def select(self, watcher):
53 if self._selected: 54 self._selected.hide() 55 if watcher: 56 self._selected = watcher 57 self._selected.show() 58 else: 59 self._selected = None
60
61 - def _setEaterFD(self, state, value):
62 if value is None: 63 self._table_connected.hide() 64 self._table_disconnected.show() 65 else: 66 self._table_disconnected.hide() 67 self._table_connected.show()
68
69 - def _setEaterName(self, state, value):
70 self.labels['eater-name'].set_markup(_('Eater <b>%s</b>') % value)
71
72 - def _setEaterBytesReadCurrent(self, state, value):
73 txt = value and (formatting.formatStorage(value) + _('Byte')) or '' 74 self.labels['bytes-read-current'].set_text(txt) 75 self._updateConnectionTime() 76 self._updateDisconnectionTime()
77
78 - def _setEaterConnectionItem(self, state, key, value):
79 if key == 'feed-id': 80 self.labels['eating-from'].set_text(str(value)) 81 # timestamps 82 elif key == 'count-timestamp-discont': 83 self.labels['timestamp-discont-count-current'].set_text(str(value)) 84 if value > 0: 85 self._expander_discont_current.show() 86 elif key == 'time-timestamp-discont': 87 text = formatting.formatTimeStamp(time.localtime(value)) 88 self.labels['timestamp-discont-time-current'].set_text(text) 89 if value is not None: 90 self._vbox_timestamp_discont_current.show() 91 elif key == 'last-timestamp-discont': 92 text = formatting.formatTime(value, fractional=9) 93 self.labels['timestamp-discont-last-current'].set_text(text) 94 if value > 0.0: 95 self._vbox_timestamp_discont_current.show() 96 elif key == 'total-timestamp-discont': 97 text = formatting.formatTime(value, fractional=9) 98 self.labels['timestamp-discont-total-current'].set_text(text) 99 if value > 0.0: 100 self._vbox_timestamp_discont_current.show() 101 elif key == 'timestamp-timestamp-discont': 102 if value is None: 103 return 104 text = formatting.formatTime(value, fractional=9) 105 self.labels['timestamp-discont-timestamp-current'].set_text(text) 106 # offsets 107 elif key == 'count-offset-discont': 108 self.labels['offset-discont-count-current'].set_text(str(value)) 109 if value > 0: 110 self._expander_discont_current.show() 111 elif key == 'time-offset-discont': 112 text = formatting.formatTimeStamp(time.localtime(value)) 113 self.labels['offset-discont-time-current'].set_text(text) 114 if value is not None: 115 self._vbox_offset_discont_current.show() 116 elif key == 'last-offset-discont': 117 text = _("%d units") % value 118 self.labels['offset-discont-last-current'].set_text(text) 119 if value > 0: 120 self._vbox_offset_discont_current.show() 121 elif key == 'total-offset-discont': 122 text = _("%d units") % value 123 self.labels['offset-discont-total-current'].set_text(text) 124 if value > 0: 125 self._vbox_offset_discont_current.show() 126 elif key == 'offset-offset-discont': 127 if value is None: 128 return 129 text = _("%d units") % value 130 self.labels['offset-discont-offset-current'].set_text(text) 131 if value > 0: 132 self._vbox_offset_discont_current.show()
133
134 - def _setEaterCountTimestampDiscont(self, state, value):
135 if value is None: 136 return 137 self.labels['timestamp-discont-count-total'].set_text(str(value)) 138 if value > 0.0: 139 self._expander_discont_total.show()
140
141 - def _setEaterTotalTimestampDiscont(self, state, value):
142 if value is None: 143 return 144 text = formatting.formatTime(value, fractional=9) 145 self.labels['timestamp-discont-total'].set_text(text) 146 if value > 0.0: 147 self._vbox_timestamp_discont_total.show()
148
149 - def _setEaterCountOffsetDiscont(self, state, value):
150 if value is None: 151 return 152 self.labels['offset-discont-count-total'].set_text(str(value)) 153 if value != 0: 154 self._expander_discont_total.show()
155
156 - def _setEaterTotalOffsetDiscont(self, state, value):
157 if value is None: 158 return 159 text = _("%d units") % value 160 self.labels['offset-discont-total'].set_text(text) 161 if value != 0: 162 self._vbox_offset_discont_total.show()
163
164 - def _setEaterLastConnect(self, state, value):
165 if value: 166 text = formatting.formatTimeStamp(time.localtime(value)) 167 self.labels['connected-since'].set_text(text) 168 self._table_connected.show() 169 self._table_disconnected.hide() 170 self._lastConnect = value 171 self._updateConnectionTime()
172
173 - def _setEaterTotalConnections(self, state, value):
174 self.labels['connections-total'].set_text(str(value))
175 176 # when we initially get the uiState, connection is an already set dict 177 # this makes sure we handle getting that dict initially 178
179 - def _setEaterConnection(self, state, value):
180 # can be called with None value due to StateWatcher 181 if value is None: 182 return 183 for k, v in value.items(): 184 self._setEaterConnectionItem(state, k, v)
185 186 # FIXME: add a timeout to update this ? 187
188 - def _updateConnectionTime(self):
189 if self._lastConnect: 190 text = formatting.formatTime(time.time() - self._lastConnect) 191 self.labels['connection-time'].set_text(text)
192 193 # FIXME: add a timeout to update this ? 194
195 - def _updateDisconnectionTime(self):
196 if self._lastDisconnect: 197 text = formatting.formatTime(time.time() - self._lastDisconnect) 198 self.labels['disconnection-time'].set_text(text)
199
200 - def addEater(self, uiState, state):
201 """ 202 @param uiState: the component's uiState 203 @param state: the eater's uiState 204 """ 205 eaterId = state.get('eater-alias') 206 i = self.treemodel.append(None) 207 self.treemodel.set(i, 0, eaterId, 1, state) 208 w = StateWatcher(state, 209 { 210 'fd': self._setEaterFD, 211 'eater-alias': self._setEaterName, 212 'last-connect': self._setEaterLastConnect, 213 'count-timestamp-discont': self._setEaterCountTimestampDiscont, 214 'total-timestamp-discont': self._setEaterTotalTimestampDiscont, 215 'count-offset-discont': self._setEaterCountOffsetDiscont, 216 'total-offset-discont': self._setEaterTotalOffsetDiscont, 217 'total-connections': self._setEaterTotalConnections, 218 # need to have a setter for connection to be able to show 219 # it initially 220 'connection': self._setEaterConnection, 221 }, 222 {}, 223 {}, 224 setitemers={'connection': self._setEaterConnectionItem, 225 }, 226 delitemers={}) 227 self.treemodel.set(i, 2, w)
228
229 - def setUIState(self, state):
230 # will only be called when we have a widget tree 231 BaseAdminGtkNode.setUIState(self, state) 232 #self.widget.show_all() 233 for eater in state.get('eaters'): 234 self.addEater(state, eater)
235
236 - def haveWidgetTree(self):
237 self.labels = {} 238 self.widget = self.wtree.get_widget('eaters-widget') 239 self.treeview = self.wtree.get_widget('treeview-eaters') 240 # tree model is a model of id, uiState, StateWatcher 241 self.treemodel = gtk.TreeStore(str, object, object) 242 self.treeview.set_model(self.treemodel) 243 col = gtk.TreeViewColumn('Eater', gtk.CellRendererText(), 244 text=0) 245 self.treeview.append_column(col) 246 sel = self.treeview.get_selection() 247 sel.set_mode(gtk.SELECTION_SINGLE) 248 249 # get to know and set labels 250 251 def set_label(name): 252 self.labels[name] = self.wtree.get_widget('label-' + name) 253 if self.labels[name] is None: 254 raise KeyError(name) 255 # zeroes out all value labels 256 self.labels[name].set_text('')
257 258 for name in ( 259 'eater-name', 'connected-since', 'connection-time', 260 'eating-from', 'timestamp-discont-timestamp-current', 261 'offset-discont-offset-current', 262 'timestamp-discont-count-current', 'offset-discont-count-current', 263 'timestamp-discont-total-current', 'offset-discont-total-current', 264 'timestamp-discont-last-current', 'offset-discont-last-current', 265 'timestamp-discont-time-current', 'offset-discont-time-current', 266 'timestamp-discont-count-total', 'offset-discont-count-total', 267 'timestamp-discont-total', 'offset-discont-total', 268 'connections-total', 269 ): 270 set_label(name) 271 272 # handle selection changes on the tree widget 273 274 def sel_changed(sel): 275 model, i = sel.get_selected() 276 self.select(i and model.get_value(i, 2)) 277 self.wtree.get_widget('box-right').show()
278 279 sel.connect('changed', sel_changed) 280 281 # manage visibility of parts of the widget 282 self._table_connected = self.wtree.get_widget( 283 'table-current-connected') 284 self._table_disconnected = self.wtree.get_widget( 285 'table-current-disconnected') 286 self._table_eater = self.wtree.get_widget('table-eater') 287 self._expander_discont_current = self.wtree.get_widget( 288 'expander-discont-current') 289 self._vbox_timestamp_discont_current = self.wtree.get_widget( 290 'vbox-timestamp-discont-current') 291 self._vbox_offset_discont_current = self.wtree.get_widget( 292 'vbox-offset-discont-current') 293 294 self._expander_discont_total = self.wtree.get_widget( 295 'expander-discont-total') 296 self._vbox_timestamp_discont_total = self.wtree.get_widget( 297 'vbox-timestamp-discont-total') 298 self._vbox_offset_discont_total = self.wtree.get_widget( 299 'vbox-offset-discont-total') 300 # 301 # show the tree view always 302 self.wtree.get_widget('scrolledwindow').show_all() 303 304 # hide the specifics of the eater 305 self._expander_discont_current.hide() 306 self._table_connected.hide() 307 self._table_disconnected.hide() 308 self._expander_discont_total.hide() 309 310 # show the right box only when an eater is selected 311 self.wtree.get_widget('box-right').hide() 312 313 # FIXME: do not show all; 314 # hide bytes fed and buffers dropped until something is selected 315 # see #575 316 self.widget.show() 317 return self.widget 318