Package flumotion :: Package component :: Package misc :: Package httpserver :: Module admin_gtk
[hide private]

Source Code for Module flumotion.component.misc.httpserver.admin_gtk

  1  # -*- Mode: Python -*- 
  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  import time 
 19  import gettext 
 20  import os 
 21  import webbrowser 
 22  import gtk 
 23   
 24  from flumotion.common.i18n import N_ 
 25  from flumotion.common import format as formatting 
 26  from flumotion.component.base.admin_gtk import BaseAdminGtk 
 27  from flumotion.component.base.baseadminnode import BaseAdminGtkNode 
 28  from flumotion.ui.linkwidget import LinkWidget 
 29  from flumotion.component.misc.httpserver.ondemandbrowser import OnDemandBrowser 
 30   
 31  __version__ = "$Rev$" 
 32  _ = gettext.gettext 
 33   
 34   
35 -class StatisticsAdminGtkNode(BaseAdminGtkNode):
36
37 - def __init__(self, *args, **kwargs):
38 BaseAdminGtkNode.__init__(self, *args, **kwargs) 39 self._shown = False 40 self._state = None 41 self._reqStats = {} # {name: (widget, converter, format, default)}
42 43 # BaseAdminGtkNode 44
45 - def haveWidgetTree(self):
46 self._reqStats = {} 47 self.widget = self._initWidgets(self.wtree) 48 if self._state: 49 self._shown = True 50 self._refreshStats(self._state) 51 self.widget.show() 52 else: 53 self._defaultStats() 54 return self.widget
55 56 # Public API 57
58 - def setStats(self, state):
59 """Update the state containing all information used by this 60 interface 61 @param state: 62 @type state: AdminComponentUIState 63 """ 64 # Set _stats regardless of if condition 65 # Used to be a race where _stats was 66 # not set if widget tree was gotten before 67 # ui state 68 self._state = state 69 70 if not self.widget: 71 # widget tree not created yet 72 return 73 74 # Update the statistics 75 self._refreshStats(state) 76 77 self._onStateSet(state) 78 79 if not self._shown: 80 # widget tree created but not yet shown 81 self._shown = True 82 self.widget.show_all()
83 84 # Protected 85
86 - def _initWidgets(self, wtree):
87 raise NotImplementedError
88
89 - def _onStateSet(self, state):
90 pass
91
92 - def _defaultStats(self):
93 pass
94
95 - def _refreshStats(self, state):
96 pass
97 98 # Private 99
100 - def _regReqStat(self, name, converter=str, formatString="%s", default=0):
101 widget = self.wtree.get_widget('label-' + name) 102 if not widget: 103 self.warning("FIXME: no widget %s" % name) 104 return 105 self._reqStats[name] = (widget, converter, formatString, default)
106
107 - def _refreshStatistics(self, state):
108 for name in self._reqStats: 109 widget, converter, formatString, default = self._reqStats[name] 110 value = state.get(name) 111 if value is not None: 112 widget.set_text(formatString % converter(value)) 113 else: 114 widget.set_text(formatString % converter(default))
115
116 - def _updateStatistic(self, name, value):
117 if name not in self._reqStats: 118 return 119 widget, converter, formatString, default = self._reqStats[name] 120 if value is not None: 121 widget.set_text(formatString % converter(value)) 122 else: 123 widget.set_text(formatString % converter(default))
124 125
126 -class ServerStatsAdminGtkNode(StatisticsAdminGtkNode):
127 gladeFile = os.path.join('flumotion', 'component', 'misc', 128 'httpserver', 'httpserver.glade') 129
130 - def __init__(self, *args, **kwargs):
131 StatisticsAdminGtkNode.__init__(self, *args, **kwargs) 132 self._uptime = None 133 self._link = None
134 135 # StatisticsAdminGtkNode 136
137 - def _initWidgets(self, wtree):
138 statistics = wtree.get_widget('main_vbox') 139 self._uptime = wtree.get_widget('label-server-uptime') 140 self._regReqStat('current-request-count', _formatClientCount) 141 self._regReqStat('mean-request-count', _formatClientCount) 142 self._regReqStat('request-count-peak', _formatClientCount) 143 self._regReqStat('request-count-peak-time', _formatTimeStamp, 144 _("at %s")) 145 self._regReqStat('current-request-rate', _formatReqRate) 146 self._regReqStat('mean-request-rate', _formatReqRate) 147 self._regReqStat('request-rate-peak', _formatReqRate) 148 self._regReqStat('request-rate-peak-time', _formatTimeStamp, 149 _("at %s")) 150 self._regReqStat('total-bytes-sent', _formatBytes) 151 self._regReqStat('current-bitrate', _formatBitrate) 152 self._regReqStat('mean-bitrate', _formatBitrate) 153 self._regReqStat('bitrate-peak', _formatBitrate) 154 self._regReqStat('bitrate-peak-time', _formatTimeStamp, _("at %s")) 155 self._regReqStat('mean-file-read-ratio', _formatPercent) 156 return statistics
157 158 # BaseAdminGtkNode 159
160 - def stateSetitem(self, state, key, subkey, value):
161 if key == "request-statistics": 162 self._updateStatistic(subkey, value)
163 164 # StatisticsAdminGtkNode 165
166 - def _refreshStats(self, state):
167 self._refreshStatistics(state.get("request-statistics", {}))
168
169 - def _defaultStats(self):
170 self._refreshStatistics({})
171
172 - def _onStateSet(self, state):
173 # Update the URI 174 uri = state.get('stream-url') 175 if uri is not None: 176 if not self._link and uri: 177 self._link = self._createLinkWidget(uri) 178 elif self._link: 179 self._link.set_uri(uri) 180 self._link.set_label(uri) 181 182 # Update Server Uptime 183 uptime = state.get('server-uptime') 184 self._uptime.set_text(formatting.formatTime(uptime))
185 186 # Private 187
188 - def _createLinkWidget(self, uri):
189 link = LinkWidget(uri) 190 link.set_callback(self._on_link_show_url) 191 link.show_all() 192 holder = self.wtree.get_widget('link-holder') 193 holder.add(link) 194 return link
195 196 # Callbacks 197
200 201
202 -class CacheStatsAdminGtkNode(StatisticsAdminGtkNode):
203 gladeFile = os.path.join('flumotion', 'component', 'misc', 204 'httpserver', 'httpserver.glade') 205
206 - def show(self):
207 if self.widget: 208 self.widget.show()
209
210 - def hide(self):
211 if self.widget: 212 self.widget.hide()
213 214 # StatisticsAdminGtkNode 215
216 - def _initWidgets(self, wtree):
217 statistics = wtree.get_widget('cache_vbox') 218 self._regReqStat('cache-usage-estimation', _formatBytes) 219 self._regReqStat('cache-usage-ratio-estimation', _formatPercent) 220 self._regReqStat('cache-hit-count') 221 self._regReqStat('temp-hit-count') 222 self._regReqStat('cache-miss-count') 223 self._regReqStat('cache-outdate-count') 224 self._regReqStat('cache-read-ratio', _formatPercent) 225 self._regReqStat('cleanup-count') 226 self._regReqStat('last-cleanup-time', _formatTimeStamp) 227 self._regReqStat('current-copy-count') 228 self._regReqStat('finished-copy-count') 229 self._regReqStat('cancelled-copy-count') 230 return statistics
231 232 233 # BaseAdminGtkNode 234
235 - def stateSetitem(self, state, key, subkey, value):
236 if key == "provider-statistics": 237 self._updateStatistic(subkey, value)
238 239 # StatisticsAdminGtkNode 240
241 - def _refreshStats(self, state):
242 self._refreshStatistics(state.get("provider-statistics", {}))
243
244 - def _defaultStats(self):
245 self._refreshStatistics({})
246 247
248 -def _formatClientCount(value):
249 if isinstance(value, (int, long)): 250 template = gettext.ngettext( 251 N_("%d client"), N_("%d clients"), value) 252 else: 253 template = gettext.ngettext( 254 N_("%.2f client"), N_("%.2f clients"), value) 255 return template % value
256 257
258 -def _formatTimeStamp(value):
259 return time.strftime("%c", time.localtime(value))
260 261
262 -def _formatReqRate(value):
263 return _("%.2f requests/m") % float(value * 60)
264 265
266 -def _formatBytes(value):
267 return formatting.formatStorage(value) + _('Byte')
268 269
270 -def _formatBitrate(value):
271 return formatting.formatStorage(value) + _('bit/s')
272 273
274 -def _formatPercent(value):
275 return "%.2f %%" % (value * 100.0)
276 277
278 -class BrowserAdminGtkNode(BaseAdminGtkNode):
279 gladeFile = os.path.join('flumotion', 'component', 'misc', 280 'httpserver', 'httpserver.glade') 281
282 - def __init__(self, state, admin, title=None):
283 BaseAdminGtkNode.__init__(self, state, admin, title) 284 self.browser = self._create_browser() 285 self._path = self.state.get('config').get('properties').get('path')
286
287 - def haveWidgetTree(self):
288 self.widget = self.wtree.get_widget('browser_vbox') 289 self.widget.connect('realize', self._on_realize) 290 self.widget.pack_start(self.browser) 291 self.browser.show() 292 self.widget.show_all() 293 return self.widget
294
295 - def setUIState(self, state):
296 BaseAdminGtkNode.setUIState(self, state) 297 if self._path and state.hasKey('allow-browsing') \ 298 and state.get('allow-browsing'): 299 self.browser.setBaseUri(state.get('stream-url')) 300 else: 301 self.browser.hide_all() 302 warning = gtk.Label() 303 warning.set_markup(_('Browsing files is not allowed.')) 304 warning.show() 305 self.widget.pack_start(warning)
306
307 - def _create_browser(self):
308 browser = OnDemandBrowser(self.widget, self.admin) 309 worker_name = self.state.get('workerRequested') 310 browser.setWorkerName(worker_name) 311 browser.connect('selected', self._on_file_selector__selected) 312 return browser
313
314 - def _configure_browser(self):
315 if self._path: 316 self.browser.setRoot(self._path)
317
318 - def _on_realize(self, widget):
319 self._configure_browser()
320
321 - def _on_file_selector__selected(self, browser, vfsFile):
322 webbrowser.open_new(vfsFile.filename)
323 324
325 -class HTTPFileAdminGtk(BaseAdminGtk):
326
327 - def setup(self):
328 statistics = ServerStatsAdminGtkNode(self.state, self.admin, 329 _("Statistics")) 330 331 browser = BrowserAdminGtkNode(self.state, self.admin, 332 _("Browser")) 333 self.nodes['Statistics'] = statistics 334 self.nodes['Browser'] = browser 335 #FIXME: We need to figure out how to create or delete 336 # a nodes after receiving the UI State, 337 # so we do not have a cache tab when not using a caching plug. 338 #cache = CacheStatsAdminGtkNode(self.state, self.admin, _("Cache")) 339 #self.nodes["Cache"] = cache 340 # FIXME: maybe make a protocol instead of overriding 341 return BaseAdminGtk.setup(self)
342
343 - def uiStateChanged(self, state):
344 self.nodes['Statistics'].setStats(state)
345 #FIXME: Same as for the setup method. 346 #if state: 347 # providerName = None 348 # providerStats = state.get("provider-statistics") 349 # if providerStats: 350 # providerName = providerStats.get("provider-name") 351 # if providerName and providerName.startswith("cached-"): 352 # self.nodes['Cache'].setStats(state) 353 # self.nodes["Cache"].show() 354 # else: 355 # self.nodes["Cache"].hide() 356 357 358 GUIClass = HTTPFileAdminGtk 359