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