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
Exemplo n.º 4
0
    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
Exemplo n.º 5
0
    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
Exemplo n.º 6
0
 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
Exemplo n.º 7
0
 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
Exemplo n.º 8
0
	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
Exemplo n.º 9
0
    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
Exemplo n.º 10
0
 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
Exemplo n.º 11
0
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
Exemplo n.º 12
0
    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
Exemplo n.º 14
0
    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
Exemplo n.º 15
0
 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))
Exemplo n.º 17
0
	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
Exemplo n.º 18
0
    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)
Exemplo n.º 21
0
    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
Exemplo n.º 22
0
 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' )