def render_content(self, ctx, data): role = self.getRole(ctx) if role == 0: return self.renderAlert('You are not authorized') return loaders.xmlfile(webappPath('agent/index.html'))
def render_content(self, ctx, data): # FIXME: should check roles yield self.getBasicAgentInfo(ctx) if self.agentInfo is None: returnValue(self.renderAlert("Couldn't retrieve information for agent %s" % self.agentUuid)) else: returnValue(loaders.xmlfile(webappPath('agent/loadinfo.html')))
class MainMenu(rend.Fragment): docFactory = loaders.xmlfile(webappPath('mainmenu.html')) def __init__(self): self.menu = Menu() rend.Fragment.__init__(self) def render_menu(self, ctx, data): return self.menu
def render_content(self, ctx, data): # FIXME: should check roles yield self.getBasicAgentInfo(ctx) if self.agentInfo is None: returnValue( self.renderAlert("Couldn't retrieve information for agent %s" % self.agentUuid)) else: returnValue(loaders.xmlfile(webappPath('agent/loadinfo.html')))
def workloadType(self, ctx, wltypeName): session = inevow.ISession(ctx) if self.workloadTypes is None: self.workloadTypes = yield session.agent.expsvcAgent.getWorkloadTypes( agentId=self.agentId) wltype = self.workloadTypes[wltypeName] wlcDescriptions = [T.li[wlclasses[wlc][1]] for wlc in wltype.wlclass] ctx.fillSlots('name', wltypeName) ctx.fillSlots('module', wltype.module) ctx.fillSlots('path', wltype.path) ctx.fillSlots('classes', T.ul()[wlcDescriptions]) self.data_workloadParams = [] for paramName, param in wltype.params.iteritems(): if param.flags & TSWLParamCommon.WLPF_OPTIONAL: paramName = T.span[paramName, T.sup['OPT']] wlpType = WLParamHelper.getTypeName(param) minVal, maxVal = WLParamHelper.getIntegerRange(param) lenVal = WLParamHelper.getStringLength(param) range = 'None' if minVal is not None and maxVal is not None: range = '[%s...%s]' % (_wlparamToStr( minVal, param), _wlparamToStr(maxVal, param)) elif lenVal is not None: range = 'len: %s' % lenVal default = WLParamHelper.getDefaultValue(param) if default is not None: default = _wlparamToStr(default, param) else: default = 'None' self.data_workloadParams.append({ 'param': paramName, 'type': wlpType, 'range': range, 'default': default, 'description': param.description }) wltparams = loaders.xmlfile(webappPath('agent/wltypeparam.html')) returnValue(wltparams)
def workloadType(self, ctx, wltypeName): session = inevow.ISession(ctx) if self.workloadTypes is None: self.workloadTypes = yield session.agent.expsvcAgent.getWorkloadTypes(agentId = self.agentId) wltype = self.workloadTypes[wltypeName] wlcDescriptions = [T.li[wlclasses[wlc][1]] for wlc in wltype.wlclass] ctx.fillSlots('name', wltypeName) ctx.fillSlots('module', wltype.module) ctx.fillSlots('path', wltype.path) ctx.fillSlots('classes', T.ul()[wlcDescriptions]) self.data_workloadParams = [] for paramName, param in wltype.params.iteritems(): if param.flags & TSWLParamCommon.WLPF_OPTIONAL: paramName = T.span[paramName, T.sup['OPT']] wlpType = WLParamHelper.getTypeName(param) minVal, maxVal = WLParamHelper.getIntegerRange(param) lenVal = WLParamHelper.getStringLength(param) range = 'None' if minVal is not None and maxVal is not None: range = '[%s...%s]' % (_wlparamToStr(minVal, param), _wlparamToStr(maxVal, param)) elif lenVal is not None: range = 'len: %s' % lenVal default = WLParamHelper.getDefaultValue(param) if default is not None: default = _wlparamToStr(default, param) else: default = 'None' self.data_workloadParams.append({'param': paramName, 'type': wlpType, 'range': range, 'default': default, 'description': param.description}) wltparams = loaders.xmlfile(webappPath('agent/wltypeparam.html')) returnValue(wltparams)
class Menu(rend.Fragment): docFactory = loaders.xmlfile(webappPath('menu.html')) navClass = 'nav' def __init__(self): self.data_menuItems = [] rend.Fragment.__init__(self) def render_navPanel(self, ctx, data): # Intermediate renderer that changes navClass # Doesn't know, how to make nevow:attr work here :( ctx.tag(_class = self.navClass) return self.render_sequence(ctx, data) def addItem(self, title, url, isActive = False, isDisabled = False): liClass = 'active' if isActive else 'disabled' if isDisabled else '' self.data_menuItems.append({'title': title, 'url': url, 'liClass': liClass})
def agentCommonInfo(self, ctx): agentInfo = self.agentInfo clientInfo = self.clientInfo if clientInfo is None: clientStateImg = T.img(src = '/images/cl-status/dead.png') clientState = 'disconnected' clientId = 'N/A' clientUuid = 'N/A' clientEndpoint = 'N/A' else: clientStateImg = T.img(src = '/images/cl-status/established.png') clientState = 'established' clientId = clientInfo.id clientUuid = clientInfo.uuid clientEndpoint = clientInfo.endpoint for slot, data in [('hostname', agentInfo.hostname), ('domainname', agentInfo.domainname), ('osname', agentInfo.osname), ('release', agentInfo.release), ('arch', agentInfo.machineArch), ('numCPUs', agentInfo.numCPUs), ('numCores', agentInfo.numCores), ('memTotal', agentInfo.memTotal), ('agentId', agentInfo.agentId), ('lastOnline', agentInfo.lastOnline), ('clientStateImg', clientStateImg), ('clientState', clientState), ('clientId', clientId), ('clientUuid', clientUuid), ('clientEndpoint', clientEndpoint)]: ctx.fillSlots(slot, data) return loaders.xmlfile(webappPath('agent/loadinfoagent.html'))
def agentCommonInfo(self, ctx): agentInfo = self.agentInfo clientInfo = self.clientInfo if clientInfo is None: clientStateImg = T.img(src='/images/cl-status/dead.png') clientState = 'disconnected' clientId = 'N/A' clientUuid = 'N/A' clientEndpoint = 'N/A' else: clientStateImg = T.img(src='/images/cl-status/established.png') clientState = 'established' clientId = clientInfo.id clientUuid = clientInfo.uuid clientEndpoint = clientInfo.endpoint for slot, data in [('hostname', agentInfo.hostname), ('domainname', agentInfo.domainname), ('osname', agentInfo.osname), ('release', agentInfo.release), ('arch', agentInfo.machineArch), ('numCPUs', agentInfo.numCPUs), ('numCores', agentInfo.numCores), ('memTotal', agentInfo.memTotal), ('agentId', agentInfo.agentId), ('lastOnline', agentInfo.lastOnline), ('clientStateImg', clientStateImg), ('clientState', clientState), ('clientId', clientId), ('clientUuid', clientUuid), ('clientEndpoint', clientEndpoint)]: ctx.fillSlots(slot, data) return loaders.xmlfile(webappPath('agent/loadinfoagent.html'))
class TreeView(rend.Fragment): searchPlaceholder = '' # TODO: Dynamic filters like in Paginated view # TODO: Collapse/Expand all docFactory = loaders.xmlfile(webappPath('treeview.html')) def __init__(self, parent, sessionUid): self.elementList = [] self.filteredElementList = self.elementList self.sessionUid = sessionUid def addElement(self, element): self.elementList.append(element) def render_searchForm(self, ctx, data): return T.div[ctx.tag(onkeyup=livepage.server.handle('search', livepage.get('searchForm').value), placeholder=self.searchPlaceholder)] def handle_search(self, ctx, query): pass def render_treeView(self, ctx, data): root_tags = [element.doRender() for element in self.filteredElementList if element.parent is None] return T.div(_class = 'tree well')[T.ul[root_tags]] def render_customControls(self, ctx, data): '''Generic method that renders custom controls (i.e. various filters)''' return ''
def render_mainTable(self, ctx, data): return loaders.xmlfile(webappPath('agent/client.html'))
config.readConfig('web.cfg') config.setWorkDir('tsweb') logging.initLogging() from tsload.web import webappPath from tsload.web.main import MainPage, AboutPage from tsload.web.login import LoginPage, LogoutPage from tsload.web.agent import AgentPage from tsload.web.profile import ProfilePage main = MainPage() # Static directories main.putChild('bootstrap', File(webappPath('bootstrap'))) main.putChild('css', File(webappPath('css'))) main.putChild('js', File(webappPath('js'))) main.putChild('images', File(webappPath('images'))) # Pages main.putChild('about', AboutPage()) main.putChild('login', LoginPage()) main.putChild('logout', LogoutPage()) main.putChild('agent', AgentPage()) main.putChild('profile', ProfilePage()) site = NevowSite(main, logPath=config.get('logging', 'logaccess')) port = config.getInt('tsweb', 'port')
def render_CSS(self, ctx, data): return file(webappPath('css/login.css')).read()
class PaginatedView(rend.Fragment): '''Provides paginated and filtered view of sequencable data. rawData is kept in rawData array. If no filter were invoked, filteredData simply references this list. If doFilter called, new list is constructed. After each change of page, filteredData is spliced into paginatedData and field named data_* (based on paginatedDataField) set for Nevow sequence renderer. It is also needs small fix to liveglue.js: var anchorIndex = base_url.indexOf('#'); if (anchorIndex != -1) { base_url = base_url.substring(0, anchorIndex); } Have three class variables: elementsPerPage - number of elements set on page paginatedDataField - name of data field used by nevow renderer to render mainTable searchPlaceholder - label shown in search field until user start typing query ''' elementsPerPage = 20 paginatedDataField = 'data_default' searchPlaceholder = 'Search...' docFactory = loaders.xmlfile(webappPath('pageview.html')) def __init__(self, parent, sessionUid): '''Initialize table view @param parent: parent page that owns that view @param sessionUid: uid of session (needed to check if liveclient request are not fake) ''' self.rawData = [] self.prefilteredData = self.rawData self.filteredData = self.prefilteredData self.paginatedData = [] self.pageId = 0 self.sessionUid = sessionUid # Livepage seeks for page/handlers inside Page, not fragment, so add references # XXX: May be we should simply play with contexts? parent.handle_page = self.handle_page parent.handle_search = self.handle_search self.parent = parent rend.Fragment.__init__(self) def add(self, row): '''Append data row to rawData''' self.rawData.append(row) def getNumPages(self): '''Returns number of pages in view''' dataLength = len(self.filteredData) lastPage = dataLength % self.elementsPerPage != 0 lastPageNum = 1 if lastPage else 0 return dataLength / self.elementsPerPage + lastPageNum def setPage(self, pageId): self.pageId = pageId start = pageId * self.elementsPerPage end = min(start + self.elementsPerPage, len(self.filteredData)) self.paginatedData = self.filteredData[start:end] # Add reference for Nevow renderer setattr(self.parent, self.paginatedDataField, self.paginatedData) setattr(self, self.paginatedDataField, self.paginatedData) def render_searchForm(self, ctx, data): return T.div[T.span(_class='label label-info', style='visibility: hidden', id='searchNotification'), ' ', ctx.tag(onkeyup=livepage.server. handle('search', livepage.get('searchForm').value), placeholder=self.searchPlaceholder)] def handle_search(self, ctx, query): if query == '': self.filteredData = self.prefilteredData yield self._searchNotify('') else: filterF = partial(self.doFilter, query) self.filteredData = filter(filterF, self.prefilteredData) if len(self.filteredData) == 0: self.filteredData = self.prefilteredData yield self._searchNotify('No results found') else: yield self._searchNotify('Found %s results' % len(self.filteredData)) self.setPage(0) yield self.update(ctx) def _searchNotify(self, notification): visibility = 'visible' if notification else 'hidden' visJS = "document.getElementById('searchNotification').style.visibility='%s'" % visibility yield livepage.set('searchNotification', notification), livepage.eol yield livepage.js(visJS), livepage.eol def render_pagination(self, ctx, data): pagin = T.ul(id='pagination') numPages = self.getNumPages() request = inevow.IRequest(ctx) href = str(request.URLPath()) def createPageLink(pageId, pageTitle, isActive=False): _ = pagin[T.li(_class='active' if isActive else '')[T.a( onclick=livepage.server.handle('page', pageId), href='#')[pageTitle]]] firstPage = max(self.pageId - 1, 0) lastPage = min(firstPage + 3, numPages) # print 'first: %d last: %d num: %d cur: %d' % (firstPage, lastPage, numPages, self.pageId) if firstPage > 0: createPageLink(0, '<<') if self.pageId > 0: createPageLink(self.pageId - 1, '<') pageList = map(lambda p: (p, str(p + 1)), range(firstPage, lastPage)) for pageId, pageTitle in pageList: createPageLink(pageId, pageTitle, pageId == self.pageId) if self.pageId < (numPages - 1): createPageLink(self.pageId + 1, '>') if lastPage < numPages: createPageLink(numPages, '>>') return pagin def handle_page(self, ctx, pageId): pageId = int(pageId) self.setPage(pageId) yield self.update(ctx) def update(self, ctx): '''Emit paginated view update''' session = inevow.ISession(ctx) # Verify if live request came from same session, our view was created # Nevow doesn't do it :( if session.uid == self.sessionUid: # nevow.livepage has problems with flattening complex objects # so render it into string prematurely flt = flat.flatten(self.render_mainTable(ctx, None), ctx) yield livepage.set('pagination', self.render_pagination(ctx, None)), livepage.eol yield livepage.set('mainTable', flt) def doFilter(self, criteria, row): '''Generic method that applies filter to table''' return True def render_mainTable(self, ctx, data): '''Generic method that renders main table''' return '' def render_customControls(self, ctx, data): '''Generic method that renders custom controls (i.e. various filters)''' return ''
def render_content(self, ctx, data): return loaders.xmlfile(webappPath('login.html'))
config.readConfig('web.cfg') config.setWorkDir('tsweb') logging.initLogging() from tsload.web import webappPath from tsload.web.main import MainPage, AboutPage from tsload.web.login import LoginPage, LogoutPage from tsload.web.agent import AgentPage from tsload.web.profile import ProfilePage main = MainPage() # Static directories main.putChild('bootstrap', File(webappPath('bootstrap'))) main.putChild('css', File(webappPath('css'))) main.putChild('js', File(webappPath('js'))) main.putChild('images', File(webappPath('images'))) # Pages main.putChild('about', AboutPage()) main.putChild('login', LoginPage()) main.putChild('logout', LogoutPage()) main.putChild('agent', AgentPage()) main.putChild('profile', ProfilePage()) site = NevowSite(main, logPath = config.get('logging', 'logaccess')) port = config.getInt('tsweb', 'port')
class LiveMainPage(livepage.LivePage, MainPageMixin): docFactory = loaders.xmlfile(webappPath('index.html')) def render___liveglue(self, ctx, data): return T.directive('liveglue')
def render_mainTable(self, ctx, data): return loaders.xmlfile(webappPath('profile/index.html'))
def render_content(self, ctx, data): session = inevow.ISession(ctx) self.data_threadpools = [] self.data_workloads = [] profile = TSExperimentProfile.createEmptyProfile() profile.userId = self.userId profile = yield session.agent.expsvcAgent.getProfile(profileName = self.profileName, profile = profile) ctx.fillSlots('profileName', self.profileName) ctx.fillSlots('userId', profile.userId) ctx.fillSlots('description', profile.description) creationDate = time.ctime(tstimeToUnixTime(profile.creationDate)) ctx.fillSlots('creationDate', creationDate) self.agentList = yield session.agent.expsvcAgent.listAgents() # XXX: agentList uses uuids as index, JSON-TS usually have name (hostname) to object maps, # and we need agentId. Possibly listAgents have to be redesigned. urlRoot = url.URL.fromContext(ctx).click('/') agentRoot = urlRoot.child('agent').child('load') def _agentInfo(agentId): for agentUuid, agent in self.agentList.iteritems(): if agent.agentId == agentId: agentName = '%s (%d)' % (agent.hostname, agent.agentId) agentHref = agentRoot.child(agentUuid) return agentName, agentHref return '', '#' for threadpoolName, threadpool in profile.threadpools.iteritems(): agentName, agentHref = _agentInfo(threadpool.agentId) self.data_threadpools.append({'name': threadpoolName, 'agentName': agentName, 'agentHref': agentHref, 'numWorkers': str(threadpool.numWorkers)}) for workloadName, workload in profile.workloads.iteritems(): agentName, agentHref = _agentInfo(threadpool.agentId) workloadType = '' if workload.workloadType is None else workload.workloadType workloadTypeHref = agentHref.add('what', 'wltype').add('wlt', workloadType) threadpool = '' if workload.threadpool is None else workload.threadpool workloadHref = url.URL.fromContext(ctx).click(workloadName) self.data_workloads.append({'name': workloadName, 'workloadHref': workloadHref, 'agentName': agentName, 'agentHref': agentHref, 'workloadType': workloadType, 'workloadTypeHref': workloadTypeHref, 'threadpool': threadpool}) self.profile = profile returnValue(loaders.xmlfile(webappPath('profile/info.html')))
class MainPage(rend.Page, MainPageMixin): docFactory = loaders.xmlfile(webappPath('index.html')) def render___liveglue(self, ctx, data): return ''