def process_request(self, req): asa_resource_id = req.args.get('asa_resource', None) if not asa_resource_id is None and asa_resource_id.endswith('/'): req.redirect(req.href.customartifacts(asa_resource_id.strip('/'))) dbp = DBPool(self.env, InstancePool()) try: request = Request(dbp, req) except ValueError: if 'format' in req.args and req.args['format'] in ['dialog', 'json']: raise return 'unable_to_retrieve_resource.html', {}, None #add_javascript(req, 'customartifacts/js/lib/jstree/jquery.jstree.js') #add_javascript(req, 'customartifacts/js/indextree.js') add_javascript(req, 'customartifacts/js/index.js') if req.environ.get('PATH_INFO', '')[-5:] == 'pages' or req.args.get('asa_resource_type', None) == 'artifact': add_stylesheet(req, 'common/css/search.css') res = Core._get_resource(request.obj) if not request.obj in (Entity, Instance, None) and not type(request.obj)==unicode else None result = request.view(request, dbp, request.obj, res) if not request.req.get_header('Content-Length') is None: # we've written directly to the request object pass else: if not result: raise Exception("No data returned by view '%s'" % request.view.__name__) return result
def render_admin_panel(self, req, cat, page, svnhooks_name): req.perm.require('REPOSITORY_ADMIN') data = {} obj = SVNHooksModel(self.env) if req.method == 'POST': if req.args.get('add') : hook = req.args.get('hook').strip() path = req.args.get('path').strip() validate_path=obj.validate(path,hook) if validate_path > 0: add_warning(req,_('Already exists')) else: obj.insert( path, hook) add_notice(req, _('Added SVN hook "%s" for path :%s successfully' %(self._hooks_info()[hook], path))) elif req.args.get('remove'): sel = req.args.get('sel') if not sel: raise TracError(_('No hook selected')) if not isinstance(sel, list): sel = [sel] for id in sel: path, hook = obj.get_by_id(id) obj.delete(id) add_notice(req, _('Hooks "%s" for path :%s deleted successfully' %(self._hooks_info()[hook], path))) req.redirect(req.href.admin(cat, page)) add_stylesheet(req, 'svnhooks/css/svnhooks.css') add_javascript(req, 'svnhooks/js/svnhooks.js') data['svnhooks'] = obj.getall() data['svnhook_names'] = self._hooks_info(type='name') data['svnhook_descriptions'] = self._hooks_info(type='description') return 'admin-svnhooks.html', data
def filter_stream(self, req, method, filename, stream, data): if filename == 'browser.html' and req.method == 'GET': # we can only work from the 'dir' view at the moment if data.get('file'): return stream # TODO check that contextmenu's InternalNameHolder is enabled, as our js needs it? add_stylesheet(req, 'sourcesharer/filebox.css') add_javascript(req, 'sourcesharer/filebox.js') # Render the filebox template for stream insertion # TODO introduce a new interface to allow putting extra buttons into this filebox? tmpl = TemplateLoader(self.get_templates_dirs()).load('filebox.html') filebox = tmpl.generate(href=req.href, reponame=data['reponame'] or '', rev=data['rev'], files=[]) # Wrap and float dirlist table, add filebox div # TODO change the id names, left/right seems a bit generic to assume we can have to ourselves stream |= Transformer('//table[@id="dirlist"]').wrap(tag.div(id="outer",style="clear:both")).wrap(tag.div(id="left")) stream |= Transformer('//div[@id="outer"]').append(tag.div(filebox, id="right")) is_svn_repo = False if 'repos' in data: is_svn_repo = isinstance(data.get('repos'), (SvnCachedRepository, SubversionRepository)) or False if is_svn_repo: add_ctxtnav(req, tag.a(_(tag.i(class_="fa fa-envelope-o")), " Send", href="", title=_("Send selected files"), id='share-files', class_='alt-button share-files-multiple'), category='ctxtnav', order=10) return stream
def get_timeline_events(self, req, start, stop, filters): """Returns a list of events in the time range given by the `start` and `stop` parameters. Full description here http://trac.edgewall.org/browser/trunk/trac/timeline/api.py """ if 'build' not in filters: return # exit if there is not any buildType in options if not self.options.get('builds', True): return # get rss feed query_string = "&".join( ['buildTypeId=%s' % id for id in self.options['builds']]) query_string += '&sinceDate=-%d' % self.options['limit'] feed_url = "%s/httpAuth/feed.html?%s" % (self.options['base_url'], query_string) tc = TeamCityQuery(self.options) try: feed = tc.xml_query(feed_url) except TeamCityError as e: self.log.error("Error while proceed TeamCity events: %s" % e) return if feed is None: self.log.error("Can't get teamcity feed") return add_stylesheet(req, 'teamcity/css/teamcity.css') add_javascript(req, 'teamcity/js/loadlog.js') # iterate over resulted xml feed for entry in feed.iterfind('{http://www.w3.org/2005/Atom}entry'): event_date = entry.find( '{http://www.w3.org/2005/Atom}published').text event_date = datetime.strptime(event_date, '%Y-%m-%dT%H:%M:%SZ') event_date = event_date.replace(tzinfo=GMT0()) if (event_date < start) or (event_date > stop): continue event_title = entry.find('{http://www.w3.org/2005/Atom}title').text event_status = entry.find( '{http://purl.org/dc/elements/1.1/}creator').text event_status = event_status.lower().replace(' ', '_') # get build id build_url = entry.find( '{http://www.w3.org/2005/Atom}link').attrib['href'] build_id, build_type = get_build_ids(build_url) # get build message if event_status == 'successful_build': msg = 'Build was successful' else: msg = 'Build failed' data = { 'date': event_date, 'status': event_status, 'title': event_title, 'build_url': build_url, 'build_type': build_type, 'build_id': build_id, 'message': msg, } yield event_status, event_date, 'ci server', data
def get_navigation_items(self, req): evil_js = '/'.join(['ctxtnavadd', 'js', 'ctxtnavadd.js']) if have_aj: add_javascript(req, evil_js) else: self._add_js_inc(req, self.env.href.chrome(evil_js)) self._add_js(req, self._make_js(req)) return [] # This returns no buttons
def get_navigation_items(self, req): evil_js = '/'.join(['ctxtnavadd','js','ctxtnavadd.js']) if have_aj: add_javascript(req, evil_js) else: self._add_js_inc(req, req.href.chrome(evil_js)) self._add_js(req,self._make_js(req)) return [] # This returns no buttons
def expand_macro(self, formatter, name, content, args): self.log.debug("SpoilerMacro: expand_macro") add_stylesheet(formatter.req, 'spoiler/css/spoiler.css') add_javascript(formatter.req, 'spoiler/js/spoiler.js') if '\n' in content: output = tag.div(class_="spoiler")(format_to_html(self.env, formatter.context,content)) else: output = tag.span(class_="spoiler")(format_to_oneliner(self.env, formatter.context,content)) self.log.debug("SpoilerMacro: expand_macro output") return output
def get_timeline_events(self, req, start, stop, filters): """Returns a list of events in the time range given by the `start` and `stop` parameters. Full description here http://trac.edgewall.org/browser/trunk/trac/timeline/api.py """ if 'build' not in filters: return # exit if there is not any buildType in options if not self.options.get('builds',True): return # get rss feed query_string = "&".join(['buildTypeId=%s' % id for id in self.options['builds']]) query_string += '&sinceDate=-%d' % self.options['limit'] feed_url = "%s/httpAuth/feed.html?%s" % (self.options['base_url'], query_string) tc = TeamCityQuery(self.options) try: feed = tc.xml_query(feed_url) except TeamCityError as e: self.log.error("Error while proceed TeamCity events: %s" % e) return if feed is None: self.log.error("Can't get teamcity feed") return add_stylesheet(req,'teamcity/css/teamcity.css') add_javascript(req,'teamcity/js/loadlog.js') # iterate over resulted xml feed for entry in feed.iterfind('{http://www.w3.org/2005/Atom}entry'): event_date = entry.find('{http://www.w3.org/2005/Atom}published').text event_date = datetime.strptime(event_date, '%Y-%m-%dT%H:%M:%SZ') event_date = event_date.replace(tzinfo=GMT0()) if (event_date < start) or (event_date > stop): continue event_title = entry.find('{http://www.w3.org/2005/Atom}title').text event_status = entry.find('{http://purl.org/dc/elements/1.1/}creator').text event_status = event_status.lower().replace(' ','_') # get build id build_url = entry.find('{http://www.w3.org/2005/Atom}link').attrib['href'] build_id, build_type = get_build_ids(build_url) # get build message if event_status == 'successful_build': msg = 'Build was successful' else: msg = 'Build failed' data = { 'date': event_date, 'status': event_status, 'title': event_title, 'build_url': build_url, 'build_type': build_type, 'build_id': build_id, 'message': msg, } yield event_status, event_date, 'ci server', data
def process_request(self, req): ''' Create a resource realm for the test item ''' EventModel = EventData(self.env, None) context = Context.from_request(req) context.realm = 'pm' ''' Render Content ''' director = self._parse_url_request(req) data = {} add_stylesheet(req, 'ht/css/pm.css') add_stylesheet(req, 'ht/css/fullcalendar.css') add_stylesheet(req, 'ht/css/jquery-ui-1.8.16.sqa.css') add_javascript(req, 'ht/js/fullcalendar.js') add_javascript(req, 'ht/js/jquery-ui-1.8.16.custom.min.js') add_javascript(req, 'ht/js/jquery.flot.js') add_javascript(req, 'ht/js/jquery.flot.pie.js') add_javascript(req, 'ht/js/pm.js') #self.log.debug("--> Got this request: %s and %s" % (req, req.args)) if (req.args.has_key('areq')): ''' Process AJAX request ''' #self.log.debug("Processing AJAX Request %s" %(req.args['areq']) ) if (req.args['areq'] == 'pm_cal_req'): ''' ''' json_data = EventModel.getEventData(req) #self.log.debug("JSON CONTENT - %s" %(json_data) ) ''' BYPASS Trac template processing Return RAW data feeds... no template ''' #self.log.debug("Length of Json String ----> %s" %(len(json_data)) ) req.send_header('content-length', len(json_data) ) req.write(json_data) return return 'pm/main.html', data, None
def expand_macro(self, formatter, name, content, args): self.log.debug("SpoilerMacro: expand_macro") add_stylesheet(formatter.req, 'spoiler/css/spoiler.css') add_javascript(formatter.req, 'spoiler/js/spoiler.js') if '\n' in content: output = tag.div(class_="spoiler")(format_to_html( self.env, formatter.context, content)) else: output = tag.span(class_="spoiler")(format_to_oneliner( self.env, formatter.context, content)) self.log.debug("SpoilerMacro: expand_macro output") return output
class TeamCityAdmin(Component): implements(IAdminPanelProvider) def get_admin_panels(self, req): if req.perm.has_permission('TEAMCITY_ADMIN'): yield ('teamcity', 'TeamCity', 'builds', 'Builds') def render_admin_panel(self, req, category, page, path_info): if not req.perm.has_permission('TEAMCITY_ADMIN'): raise HTTPForbidden('You are not allowed to configure TC plugin') if req.method == 'POST': options, errors = self._save_options(req.args) if not errors: # redirect here req.redirect(req.href(req.path_info)) else: options, errors = get_options(self.config), [] tc = TeamCityQuery(options) url = "%s/httpAuth/app/rest/buildTypes" % options['base_url'] # load builds from TC using REST API try: builds_xml = tc.xml_query(url) except TeamCityError, e: errors.append("Fix base config options: %s" % e) t_data = {'options': options, 'projects': {}, 'errors': errors} return 'teamcity_admin.html', t_data projects = {} for build in builds_xml.iterfind('buildType'): pr_name = build.attrib['projectName'] pr_id = build.attrib['projectId'] if pr_id not in projects: projects[pr_id] = { 'id': pr_id, 'name': pr_name, 'checked': False, 'builds': [] } btype_id = build.attrib['id'] if btype_id in options.get('builds', []): projects[pr_id]['checked'] = True projects[pr_id]['builds'].append({ 'btype_id': btype_id, 'btype_name': build.attrib['name'], 'btype_url': build.attrib['webUrl'], 'checked': btype_id in options.get('builds', []) }) add_stylesheet(req, 'teamcity/css/admin.css') add_javascript(req, 'teamcity/js/admin.js') t_data = {'options': options, 'projects': projects, 'errors': errors} return 'teamcity_admin.html', t_data
def _show_backlog(self, req): self.env.log.info(req.args) bklg_id = req.args.get('bklg_id',None) backlog = Backlog(self.env, bklg_id) rw = 'BACKLOG_MODIFY_%s'%backlog.name2perm() in req.perm data = {} data['backlogname'] = backlog.name data['tickets'], data['tickets2'] = backlog.get_tickets() # jquery-ui stylesheet and JS add_stylesheet(req, 'bl/css/jquery-ui-1.7.2.custom.css') add_javascript(req, 'bl/js/jquery-ui-1.7.2.custom.min.js') #backlog custom stylesheet and JS add_stylesheet(req, 'bl/css/backlog.css') if(rw): add_javascript(req, 'bl/js/backlog.rw.js') else: add_javascript(req, 'bl/js/backlog.ro.js') # This tuple is for Genshi (template_name, data, content_type) # Without data the trac layout will not appear. return 'backlog.html', data, None
def filter_stream(self, req, method, filename, stream, data): if req.authname == 'anonymous': return stream if not self.c_name or not self.c_version: return stream user_dis_obj = UserDisclaimerModel(self.env) valid = user_dis_obj.validate(req.authname, self.c_name, self.c_version) if valid: return stream obj = DisclaimerModel(self.env) disclaimer = obj.get_by_name_version(self.c_name,self.c_version) if not disclaimer: return stream (id, author, body) = disclaimer add_stylesheet(req, 'disclaimer/css/disclaimer.css') add_javascript(req, 'disclaimer/js/disclaimer.js') chrome = Chrome(self.env) template = chrome.load_template("disclaimer.html") data = dict(name=self.c_name, version=self.c_version, body=body) data = chrome.populate_data(req, data) stream |= Transformer('//div[@id="footer"]').append(template.generate(**data)) return stream
def _do_config(self, req): add_stylesheet( req, 'jenkins/css/admin_jenkins.css' ) add_javascript( req, 'jenkins/js/jquery-1.9.0.js' ) add_javascript( req, 'jenkins/js/jquery-ui-1.10.0.custom.min.js' ) add_javascript( req, 'jenkins/js/admin_jenkins.js' ) tabs = self._load_tab_data() data = { 'tabs': tabs, 'formAction': req.base_path + req.path_info } return 'admin_jenkins.html', data
def get_stream(self,req, method, filename, stream, original_data): chrome = Chrome(self.env) ticket_id = original_data['ticket'].id data = original_data data['objectlinks'] = self.get_links_for('ticket', ticket_id) data['link_types'] = get_link_types() data['components'] = [component.name for component in trac.ticket.model.Component.select(self.env)] data['return_url'] = req.href.ticket(ticket_id) template = chrome.load_template('ticket-links.html') content_stream = template.generate(**(chrome.populate_data(req, data))) chrome.add_jquery_ui(req) add_javascript(req,'objectlinking/jquery-ui-autocomplete.js') add_javascript(req,'objectlinking/search-links.js') add_javascript(req,'objectlinking/extract-ticket.js') add_stylesheet(req, 'objectlinking/style.css') add_stylesheet(req, 'objectlinking/jquery-ui-custom.css') return Transformer('//div[@id="ticket"]').after(content_stream)
def expand_macro(self, formatter, name, args): args = parse_args(args) # args is a tuple with a list of unnamed parameters (which is empty as # we don't support them), and a dictionary (named parameters) args = _get_args_defaults(formatter.env, args[1]) timezone = args.pop('timezone') if timezone == 'utc' : timezone = utc elif timezone == 'local': timezone = LocalTimeZone() else: raise Exception('parameter "timezone" was either "utc" nor ' '"local", it was: %s' % timezone) title = args.pop('title') days = int(args.pop('days')) width = int(args.pop('width')) height = int(args.pop('height')) statuses = args.pop('statuses').split('|') init_stat = args.pop('init_status') today = datetime.datetime.combine( datetime.date.today(), # last microsecond :-) of today datetime.time(23, 59, 59, 999999, tzinfo=timezone)) time_start = today - timedelta(days=days) ts_start = to_timestamp(time_start) sql_start = ts_start * 1000000 ts_end = to_timestamp(today) sql_end = ts_end * 1000000 # values for the template: data = {} data['title'] = title data['width'] = width data['height'] = height data['id'] = ''.join(str(random.randint(0,9)) for i in range(15)) # calculate db extra restrictions from extra parameters extra_parameters = [] extra_sql = '' not_allowed = re.compile(r'[^a-zA-Z0-9_]') for stat in statuses: if not_allowed.search(stat): raise Exception('a status contained not allowed characters') statuses_sql = ','.join("'{0}'".format(stat) for stat in statuses) if args: extra_sql_constraints = [] for key, value in args.items(): if not_allowed.search(key): raise Exception('a paramter contained not allowed characters') if value[0] == '!': extra_sql_constraints.append("{0} <> %s".format(key)) extra_parameters.append(value[1:]) else: extra_sql_constraints.append("{0} = %s".format(key)) extra_parameters.append(value) extra_sql = u' AND '.join(extra_sql_constraints) if hasattr(self.env, 'get_read_db'): db = self.env.get_read_db() else: db = self.env.get_db_cnx() cursor = db.cursor() series = { 'openedTickets': {}, 'closedTickets': {}, 'reopenedTickets': {}, 'openTickets': {} } # NOTE on casting times: in the sql statements below, we use: # CAST((time / 86400) AS int) * 86400 AS date # which homogenize all times during a day to the same day. Example: # The following two values will have the same value # 1386280739 (2013-12-05 22:58:59) -> 2013-12-05 00:00:00 # 1386270739 (2013-12-05 20:12:19) -> 2013-12-05 00:00:00 # number of created tickets for the time period, grouped by day # a day has 86400 seconds if init_stat in statuses: sql = 'SELECT COUNT(DISTINCT id), ' \ 'CAST((time / 86400000000) AS int) * 86400 AS date ' \ 'FROM ticket WHERE {0} {1} time BETWEEN %s AND %s ' \ 'GROUP BY date ORDER BY date ASC'.format( extra_sql, ' AND ' if extra_sql else '', statuses_sql) cursor.execute(sql, tuple(extra_parameters) + (sql_start, sql_end)) for count, timestamp in cursor: # flot needs the time in milliseconds, not seconds, see # https://github.com/flot/flot/blob/master/API.md#time-series-data series['openedTickets'][timestamp*1000] = float(count) # number of reopened tickets for the time period, grouped by day # a day has 86400 seconds cursor.execute("SELECT COUNT(DISTINCT tc.ticket), " "CAST((tc.time / 86400000000) AS int) * 86400 as date " "FROM ticket_change tc JOIN ticket t ON t.id = tc.ticket " "WHERE {0} {1} field = 'status' AND newvalue in ({2}) AND oldvalue NOT IN ({2}) " "AND tc.time BETWEEN %s AND %s " "GROUP BY date ORDER BY date ASC".format( extra_sql, ' AND ' if extra_sql else '', statuses_sql), tuple(extra_parameters) + (sql_start, sql_end)) for count, timestamp in cursor: # flot needs the time in milliseconds, not seconds, see # https://github.com/flot/flot/blob/master/API.md#time-series-data series['reopenedTickets'][float(timestamp*1000)] = float(count) # number of closed tickets for the time period, grouped by day (ms) cursor.execute("SELECT COUNT(DISTINCT ticket), " "CAST((tc.time / 86400000000) AS int) * 86400 AS date " "FROM ticket_change tc JOIN ticket t ON t.id = tc.ticket " "WHERE {0} {1} tc.field = 'status' AND tc.newvalue not in ({2}) AND tc.oldvalue in ({2})" "AND tc.time BETWEEN %s AND %s " \ "GROUP BY date ORDER BY date ASC".format( extra_sql, ' AND ' if extra_sql else '', statuses_sql), tuple(extra_parameters) + (sql_start, sql_end)) for count, timestamp in cursor: # flot needs the time in milliseconds, not seconds, see # https://github.com/flot/flot/blob/master/API.md#time-series-data series['closedTickets'][float(timestamp*1000)] = -float(count) # calculate number of open tickets for each day # number of open tickets up to now cursor.execute( "SELECT COUNT(*) FROM ticket " "WHERE {0} {1} status in ({2})".format( extra_sql, ' AND ' if extra_sql else '', statuses_sql), tuple(extra_parameters)) open_tickets = cursor.fetchone()[0] series['openTickets'][ts_end * 1000] = open_tickets formatter.env.log.debug('ts_end = {0}, ts_start = {1}'.format(ts_end, ts_start)) for day_ms in range(long(math.floor(ts_end / 86400.0) * 86400000), long(ts_start * 1000), -86400000): open_tickets -= series['closedTickets'].get(day_ms, 0) open_tickets -= series['openedTickets'].get(day_ms, 0) open_tickets -= series['reopenedTickets'].get(day_ms, 0) series['openTickets'][day_ms] = open_tickets # sort all series and put them in data for i in series: keys = series[i].keys() keys.sort() data[i] = json.dumps([(k, series[i][k]) for k in keys]) # generate output # NOTE: if you change the namespace below, you also need to change it # when using in get_htdocs_dirs add_javascript(formatter.req, 'stsm/js/excanvas.min.js') add_javascript(formatter.req, 'stsm/js/jquery.flot.min.js') add_javascript(formatter.req, 'stsm/js/jquery.flot.stack.min.js') add_javascript(formatter.req, 'stsm/js/simpleticketstats.js') template = Chrome(self.env).load_template( 'simpleticketstats_macro.html', method='text') formatter.env.log.debug(data) return Markup(template.generate(**data))
def process_request(self,req): if not req.perm.has_permission('TEAMCITY_BUILD'): raise HTTPForbidden('You are not allowed to view/run TC builds') options = get_options(self.config) tc = TeamCityQuery(options) # projects variable will collect builds result in following format: # {'projectId': { # 'name': 'Proj1', # 'btypes': [{ # it's a list of build types assigned to this project # 'btype_id': 'bt1', # 'btype_name': 'PS3 builds' # 'build': { # 'number': 5555 # teamcity number # 'status': 'Success', # 'start_date': datetime_object, # 'end_date': datetime_object, # },] # } # } projects = {} for build_type in options['builds']: # load builds xml from teamcity url = "%s/httpAuth/app/rest/buildTypes/id:%s/builds" %\ (options['base_url'],build_type) btype_xml = tc.xml_query(url) if btype_xml is None: self.log.error("Can't load builds xml at %s" % url) continue if len(btype_xml) < 1: # there is not any builds yet url = '%s/httpAuth/app/rest/buildTypes/id:%s' % (options['base_url'], build_type) build_xml = tc.xml_query(url) if build_xml is None: continue proj_id = build_xml.xpath('/buildType/project/@id')[0] # collect here as many build info as possible and continue build_info = { 'btype_id': build_type, 'btype_name': build_xml.attrib['name'], 'build': { 'id': None, 'number': None, 'status': 'unknown', 'end_date': 'Never', 'duration': 'Unknown' } } if proj_id in projects: projects[proj_id]['btypes'].append(build_info) else: # or create new item in projects projects[proj_id] = { 'name': proj_name, 'btypes': [build_info,] } continue # There is at least one finished build last_build = btype_xml[0].attrib # load this build xml url = "%s%s" % (options['base_url'],last_build['href']) build_xml = tc.xml_query(url) if build_xml is None: self.log.error("Can't load build xml at %s" % url) proj_id = build_xml.xpath('/build/buildType/@projectId')[0] proj_name = build_xml.xpath('/build/buildType/@projectName')[0] # F**k! python2.5 has not support for timezones in datetime.strptime try: # datetime lacks timezone info start_date = build_xml.xpath('/build/startDate/text()')[0].split('+')[0] start_date = datetime.strptime(start_date, '%Y%m%dT%H%M%S') # datetime lacks timezone info end_date = build_xml.xpath('/build/finishDate/text()')[0].split('+')[0] end_date = datetime.strptime(end_date, '%Y%m%dT%H%M%S') except IndexError: # no start_date or end_date, duration is unknown end_date = 'Never' duration = 'Unknown' else: duration = end_date - start_date # parse build status try: status = build_xml.xpath('/build/statusText/text()')[0].lower() except IndexError: # no last status yet status = 'unknown' # result build dictionary build_info = { 'btype_id': build_type, 'btype_name': build_xml.xpath('/build/buildType/@name')[0], 'build': { 'id': build_xml.attrib['id'], 'number': build_xml.attrib['number'], 'status': status, 'end_date': end_date, 'duration': duration } } # add new build to project if proj_id in projects: projects[proj_id]['btypes'].append(build_info) else: # or create new item in projects projects[proj_id] = { 'name': proj_name, 'btypes': [build_info,] } add_stylesheet(req,'teamcity/css/teamcity.css') add_javascript(req,'teamcity/js/jquery.timers-1.2.js') add_javascript(req,'teamcity/js/event_tracker.js') return 'teamcity_builds.html', { 'projects':projects, 'dpath':req.href('builds/download') }, None
def _show_backlog_list(self, req): db = self.env.get_db_cnx() cursor = db.cursor() self._create_ordering_table() bklg_id = req.args.get('bklg_id',None) data = {} columns = ['id', 'name'] sql = """SELECT %s, 0 as total, 0 as active FROM backlog """%(','.join(columns)) cursor.execute(sql) columns.extend(['total', 'active']) # creating dictionary with id as key of columnt:value dictionaries data['backlogs'] = dict([(backlog[0],(dict(zip(columns, backlog)))) for backlog in cursor]) # get total of tickets in each backlog sql = """SELECT bklg_id, count(*) as total FROM backlog_ticket WHERE tkt_order IS NULL OR tkt_order > -1 GROUP BY bklg_id """ cursor.execute(sql) for id, total in cursor: data['backlogs'][id]['total'] = total data['backlogs'][id]['closed'] = 0 data['backlogs'][id]['active'] = 0 # get total of tickets by status in each backlog sql = """SELECT bt.bklg_id, t.status, count(*) as total FROM backlog_ticket bt, ticket t WHERE t.id = bt.tkt_id AND (bt.tkt_order IS NULL OR bt.tkt_order > -1) GROUP BY bklg_id, status """ cursor.execute(sql) for id, status, total in cursor: print 'status', id, status, total if(status == 'closed'): data['backlogs'][id]['closed'] += total else: data['backlogs'][id]['active'] += total data['backlogs'][id]['status_%s'%status] = total data['req'] = str(dir(req)); data['args'] = str(req.args); # jquery-ui stylesheet and JS add_stylesheet(req, 'bl/css/jquery-ui-1.7.2.custom.css') add_javascript(req, 'bl/js/jquery-ui-1.7.2.custom.min.js') #backlog custom stylesheet and JS add_stylesheet(req, 'bl/css/backlog.css') # This tuple is for Genshi (template_name, data, content_type) # Without data the trac layout will not appear. return 'backlog_list.html', data, None
def process_request(self, req): offset = req.args.get("offset",0) page = req.args.get('page', 1) try: offset = int(offset) except: raise TracError(_('Invalid offset used: %(offset)s', offset=offset)) try: page = int(page) except: raise TracError(_('Invalid page used: %(page)s', page=page)) offset = (page - 1) * self.limit add_stylesheet(req, 'mailinglist/css/mailinglist.css') add_javascript(req, 'mailinglist/mailinglist.js') mailinglists = [m for m in Mailinglist.select(self.env) if "MAILINGLIST_VIEW" in req.perm(m.resource)] data = {"mailinglists": mailinglists, "offset": offset, "limit": self.limit} if req.method == 'POST': if 'subscribe' in req.args: subscribe = True unsubscribe = False mailinglist_email = req.args.get('subscribe') elif 'unsubscribe' in req.args: subscribe = False unsubscribe = True mailinglist_email = req.args.get('unsubscribe') else: # at the moment we only post subscription info to # mailing list page - so if there is none in req.args we # can just redirect to mailing list page req.redirect(req.href.mailinglist()) # get mailing list object and check permissions mailinglist = Mailinglist.select_by_address(self.env, mailinglist_email, localpart=True) req.perm(mailinglist.resource).require("MAILINGLIST_VIEW") if subscribe: mailinglist.subscribe(user=req.authname) # subscribe does not return a value to indicate if it # was successful, so we have to explicitly check if mailinglist.is_subscribed(req.authname): add_notice(req, _('You have been subscribed to %s.' % mailinglist.name)) else: add_notice(req, _('Unable to subscribe to %s.' % mailinglist.name)) elif unsubscribe: mailinglist.unsubscribe(user=req.authname) # unsubscribe does not return a value to indicate if it # was successful, so we have to explicitly check if not mailinglist.is_subscribed(req.authname): add_notice(req, _('You have been unsubscribed from %s.' % mailinglist.name)) else: add_notice(req, _('Unable to unsubscribe from %s.' % mailinglist.name)) if req.path_info.endswith('/mailinglist'): # overview mailing list page req.redirect(req.href.mailinglist()) elif 'conversationid' in req.args: # individual mailing list conversation log req.redirect(req.href.mailinglist(mailinglist_email, req.args['conversationid'])) else: # individual mailing list homepage req.redirect(req.href.mailinglist(mailinglist_email)) #for mailinglist in mailinglists: # add_ctxtnav(req, # _("List: %s") % mailinglist.name, # req.href.mailinglist(mailinglist.emailaddress)) if 'messageid' in req.args: message = MailinglistMessage(self.env, req.args['messageid']) # leaks the subject of the email in the error, wonder if # that's a problem... req.perm(message.resource).require("MAILINGLIST_VIEW") if req.args.get('format') == "raw": req.send_header('Content-Disposition', 'attachment') req.send_response(200) content = message.raw.bytes req.send_header('Content-Type', 'application/mbox') req.send_header('Content-Length', len(content)) req.end_headers() if req.method != 'HEAD': req.write(content) return context = Context.from_request(req, message.resource) data['message'] = message data['attachments'] = AttachmentModule(self.env).attachment_data(context) add_link(req, 'up', get_resource_url(self.env, message.conversation.resource, req.href, offset=data['offset']), _("Back to conversation")) prevnext_nav(req, _("Newer message"), _("Older message"), _("Back to conversation")) raw_href = get_resource_url(self.env, message.resource, req.href, format='raw') add_link(req, 'alternate', raw_href, _('mbox'), "application/mbox") if 'MAILINGLIST_ADMIN' in req.perm: add_ctxtnav(req, tag.a(tag.i(class_="fa fa-cog"), ' Manage List', href=req.href.admin('mailinglist', 'lists', message.conversation.mailinglist.emailaddress), title='Manage and subscribe users to the %s mailing list' % message.conversation.mailinglist.name)) return 'mailinglist_message.html', data, None if 'conversationid' in req.args: conversation = MailinglistConversation(self.env, req.args['conversationid']) # also leaks the subject of the first email in the error message req.perm(conversation.resource).require("MAILINGLIST_VIEW") data['conversation'] = conversation data['attachmentselect'] = partial(Attachment.select, self.env) results = Paginator(conversation.messages(), page - 1, self.limit) if results.has_next_page: next_href = get_resource_url(self.env, conversation.resource, req.href, page=page + 1) add_link(req, 'next', next_href, _('Next Page')) if results.has_previous_page: prev_href = get_resource_url(self.env, conversation.resource, req.href, page=page - 1) add_link(req, 'prev', prev_href, _('Previous Page')) shown_pages = results.get_shown_pages() pagedata = [{'href': get_resource_url(self.env, conversation.resource, req.href, page=page), 'class': None, 'string': str(page), 'title': _('Page %(num)d', num=page)} for page in shown_pages] results.shown_pages = pagedata results.current_page = {'href': None, 'class': 'current', 'string': str(results.page + 1), 'title': None} data['paginator'] = results add_link(req, 'up', get_resource_url(self.env, conversation.mailinglist.resource, req.href, offset=data['offset']), _("List of conversations")) prevnext_nav(req, _("Newer conversation"), _("Older conversation"), _("Back to list of conversations")) if 'MAILINGLIST_ADMIN' in req.perm: add_ctxtnav(req, tag.a(tag.i(class_="fa fa-cog"), ' Manage List', href=req.href.admin('mailinglist', 'lists', conversation.mailinglist.emailaddress), title='Manage and subscribe users to the %s mailing list' % conversation.mailinglist.name)) # Check if user is already subscribed to mailing list # and add the appropriate subscribe / unsubscribe ribbon option if conversation.mailinglist.is_subscribed(req.authname): add_ctxtnav(req, tag.form(tag.input(tag.a(tag.i(class_='fa fa-eye-slash'), ' Unsubscribe', title='Unsubscribe from the %s mailing list' % conversation.mailinglist.name, id='subscribe-link'), name='unsubscribe', value=conversation.mailinglist.emailaddress, class_='hidden'), method_='post', action='', id='subscribe-form', class_='hidden')) else: add_ctxtnav(req, tag.form(tag.input(tag.a(tag.i(class_='fa fa-eye'), ' Subscribe', title='Subscribe to the %s mailing list' % conversation.mailinglist.name, id='subscribe-link'), name='subscribe', value=conversation.mailinglist.emailaddress, class_='hidden'), method_='post', action='', id='subscribe-form', class_='hidden')) return 'mailinglist_conversation.html', data, None elif 'listname' in req.args: mailinglist = Mailinglist.select_by_address(self.env, req.args['listname'], localpart=True) # leaks the name of the mailinglist req.perm(mailinglist.resource).require("MAILINGLIST_VIEW") data['mailinglist'] = mailinglist results = Paginator(mailinglist.conversations(), page - 1, self.limit) if results.has_next_page: next_href = get_resource_url(self.env, mailinglist.resource, req.href, page=page + 1) add_link(req, 'next', next_href, _('Next Page')) if results.has_previous_page: prev_href = get_resource_url(self.env, mailinglist.resource, req.href, page=page - 1) add_link(req, 'prev', prev_href, _('Previous Page')) shown_pages = results.get_shown_pages() pagedata = [{'href': get_resource_url(self.env, mailinglist.resource, req.href, page=page), 'class': None, 'string': str(page), 'title': _('Page %(num)d', num=page)} for page in shown_pages] results.shown_pages = pagedata results.current_page = {'href': None, 'class': 'current', 'string': str(results.page + 1), 'title': None} data['paginator'] = results if data['offset'] + data['limit'] < mailinglist.count_conversations(): add_link(req, 'next', get_resource_url(self.env, mailinglist.resource, req.href, offset=data['offset']+data['limit']), _("Older conversations")) if offset > 0: add_link(req, 'prev', get_resource_url(self.env, mailinglist.resource, req.href, offset=data['offset']-data['limit']), _("Newer conversations")) add_link(req, 'up', req.href.mailinglist(), _("List of mailinglists")) prevnext_nav(req, _("Newer conversations"), _("Older conversations"), ("Back to Mailinglists")) if 'MAILINGLIST_ADMIN' in req.perm: add_ctxtnav(req, tag.a(tag.i(class_="fa fa-cog"), ' Manage List', href=req.href.admin('mailinglist', 'lists', mailinglist.emailaddress), title='Manage and subscribe users to the %s mailing list' % mailinglist.name)) # Check if user is already subscribed to mailing list # and add the appropriate subscribe / unsubscribe ribbon option if mailinglist.is_subscribed(req.authname): add_ctxtnav(req, tag.form(tag.input(tag.a(tag.i(class_='fa fa-eye-slash'), ' Unsubscribe', title='Unsubscribe from the %s mailing list' % mailinglist.name, id='subscribe-link'), name='unsubscribe', value=mailinglist.emailaddress, class_='hidden'), method_='post', action='', id='subscribe-form', class_='hidden')) else: add_ctxtnav(req, tag.form(tag.input(tag.a(tag.i(class_='fa fa-eye'), ' Subscribe', title='Subscribe to the %s mailing list' % mailinglist.name, id='subscribe-link'), name='subscribe', value=mailinglist.emailaddress, class_='hidden'), method_='post', action='', id='subscribe-form', class_='hidden')) return 'mailinglist_conversations.html', data, None else: return 'mailinglist_list.html', data, None
def post_process_request(self, req, template, data, content_type): Chrome(self.env).add_jquery_ui(req) add_javascript(req, "customartifacts/js/lib/ace/ace.js") add_javascript(req, "customartifacts/js/lib/ace/theme-trac_wiki.js") add_javascript(req, 'customartifacts/js/lib/jquery.balloon.js') add_javascript(req, "customartifacts/js/requests.js") add_javascript(req, 'customartifacts/js/tracking.js') add_javascript(req, "customartifacts/js/dialogs.js") add_javascript(req, 'customartifacts/js/util.js') add_javascript(req, 'customartifacts/js/uuid.js') add_javascript(req, 'customartifacts/js/forms.js') path_parts = req.environ.get('PATH_INFO', '').decode("utf-8").split("/") module_area = path_parts[1] if len(path_parts)>1 else None if module_area == 'wiki': from datetime import datetime dbp = DBPool(self.env, InstancePool()) resource_id = u"" if len(path_parts) > 2: resource_id = path_parts[2] if 'action' in req.args and req.args['action'] == 'edit': dbp.track_it("wiki", resource_id, "edit", req.authname, str(datetime.now())) else: dbp.track_it("wiki", resource_id, "view", req.authname, str(datetime.now())) page = WikiPage(dbp.env, resource_id) add_script_data(req, {'embedded_artifacts': get_embedded_artifact_ids_from_text(page.text)}) if module_area == 'wiki' and 'action' in req.args and req.args['action'] == 'edit' or \ module_area in ['ticket', 'newticket']: add_javascript(req, "customartifacts/js/wiki.js") add_script_data(req, {'baseurl': req.href.customartifacts()}) add_script_data(req, {'form_token': req.form_token}) add_stylesheet(req, 'customartifacts/css/asa.css', media='screen') add_stylesheet(req, 'customartifacts/css/wiki.css') add_stylesheet(req, 'customartifacts/css/ticket.css') add_stylesheet(req, 'customartifacts/css/index_page.css') return (template, data, content_type)
def process_request(self, req): add_javascript( req, 'htdocs/js/jquery-1.5.1.min.js' ) add_javascript( req, 'htdocs/js/jquery-ui-1.8.13.custom.min.js') add_javascript( req, 'htdocs/js/application.js') add_javascript( req, 'htdocs/js/action.js') # add_javascript( req, 'htdocs/js/actionView.js') add_javascript( req, 'htdocs/js/actionEditView.js') add_javascript( req, 'htdocs/js/component.js') add_javascript( req, 'htdocs/js/componentView.js') add_javascript( req, 'htdocs/js/componentEditView.js') add_javascript( req, 'htdocs/js/logView.js') add_javascript( req, 'htdocs/js/parametersView.js') add_javascript( req, 'htdocs/js/globalsManagerView.js') add_javascript( req, 'htdocs/js/styleDataManager.js') add_javascript( req, 'htdocs/js/screenManager.js') add_javascript( req, 'htdocs/js/dialogView.js') add_javascript( req, 'htdocs/js/menuView.js') add_javascript( req, 'htdocs/js/host.js') add_javascript( req, 'htdocs/js/infoBoxView.js') add_javascript( req, 'htdocs/js/calendarView.js') add_javascript( req, 'htdocs/js/hostManagerView.js') add_javascript( req, 'htdocs/js/userManagerView.js') add_javascript( req, 'htdocs/fancybox/jquery.fancybox-1.3.4.pack.js') add_javascript( req, 'htdocs/fullcalendar/fullcalendar.min.js') add_javascript( req, 'htdocs/js/json2.js') add_stylesheet( req, 'htdocs/Aristo/jquery-ui-1.8.7.custom.css') # add_stylesheet( req, 'htdocs/Aristo/jquery-ui-custom-icon.css') # add_stylesheet( req, 'htdocs/css/customJQuery.css') add_stylesheet( req, 'htdocs/css/actionEditView.css') add_stylesheet( req, 'htdocs/css/componentView.css') add_stylesheet( req, 'htdocs/css/componentEditView.css') add_stylesheet( req, 'htdocs/css/logView.css') add_stylesheet( req, 'htdocs/css/style.css') add_stylesheet( req, 'htdocs/css/dialogView.css') add_stylesheet( req, 'htdocs/css/infoBoxView.css') add_stylesheet( req, 'htdocs/css/adminBoxView.css') add_stylesheet( req, 'htdocs/css/userManagerView.css') add_stylesheet( req, 'htdocs/css/menuView.css') add_stylesheet( req, 'htdocs/fancybox/jquery.fancybox-1.3.4.css') add_stylesheet( req, 'htdocs/fullcalendar/fullcalendar.css') import privileges try: myPrivileges = self.loadPrivileges(req) except StartingServerException, e: return 'startingServer.html', {}, None
def _enqueue_htdocs( self, req ): add_javascript( req, 'customAuthPlugin/js/jquery-1.9.0.js' ) add_javascript( req, 'customAuthPlugin/js/jquery-ui-1.10.0.custom.min.js' ) add_stylesheet( req, 'customAuthPlugin/css/matrix.css' ) add_javascript( req, 'customAuthPlugin/js/matrix.js' ) add_javascript( req, 'customAuthPlugin/js/ajax-matrix.js' )