def expand_macro(self, formatter, name, content, args=None): """ Returns the outcome from macro. Supported arguments: - project: Name of the project to show status / provide follow buttons. Defaults to current project """ req = formatter.req # Parse optional arguments if args is None: args = parse_args(content) if len(args) > 1: args = args[1] # Read optional project name - fallback to current project_name = self.env.project_identifier if args and 'project' in args: project_name = args.get('project', '').strip() # Load project id from db project_id = Project.get(env_name=project_name).id watchers, is_watching = self._get_status(req, project_id) # If user is already watching, do not show the block if is_watching: return tag.div('') # Show macro only when user has permission to view timeline if name not in self.macros or 'TIMELINE_VIEW' not in req.perm or not project_id: # Return default content / instructions return tag.div( tag.h2(_('Follow project'), **{'class': 'title'}), tag.p(_('Project cannot be found or no permission to follow it')), **{'class': 'watch'} ) # For anonymous users, advice login/registering if req.authname == 'anonymous': return tag.div( tag.h2(_('Follow project'), **{'class': 'title'}), tag.p(_('Only registered users can follow the project activity. ')), tag.p(tag.a('Please login or register to service first', href=req.href('../home/user'))), **{'class': 'watch'} ) # Return rendered HTML with JS attached to it data = { 'project_id': project_id, 'env_name': self.env.project_identifier, 'project_name': project_name } chrome = Chrome(self.env) stream = chrome.render_template(req, 'multiproject_watch.html', data, fragment=True) if req.form_token: stream |= chrome._add_form_token(req.form_token) return stream
def expand_macro(self, formatter, name, content, args=None): """ Returns the outcome from macro. """ req = formatter.context.req # Check permissions if 'TIMELINE_VIEW' not in req.perm: # Return default content / instructions return tag.div( tag.h2(_('Project team'), **{'class': 'title'}), tag.p(_('Project team cannot be found or no permission to follow it')), **{'class': 'watch'} ) # Load project info from optional project argument. Defaults to current env project = Project.get(self.env) team, members = self._get_team_info(project) # Return rendered HTML with JS attached to it data = { 'project_id': project.id, 'env_name': self.env.project_identifier, 'project_name': self.env.project_identifier, # TODO: redundant 'team': team, 'members': members } # NOTE: Use fragment to not to recreate chrome (add_script does not work) and run post processing manually chrome = Chrome(self.env) stream = chrome.render_template(req, 'multiproject_team.html', data, fragment=True) if req.form_token: stream |= chrome._add_form_token(req.form_token) return stream
def process_request(self, req): """ Handles the request :param req: Request :return: json """ if req.method != 'POST': raise TracError('Invalid request') req.perm.require('TIMELINE_VIEW') userstore = get_userstore() watchstore = CQDEWatchlistStore() action = req.args.get('action') project_id = 0 # Determine project id from URL match = REQ_REGEXP.match(req.path_info) if match: project_id = int(match.group('pid')) # Load userinfo user = userstore.getUser(req.authname) uid = user.id if user else None #load project project = Project.get(id=project_id) # Start following if action == 'watch': watchstore.watch_project(uid, project_id) # Notify listeners. for listener in self.project_change_listeners: try: listener.project_watchers(project) except: pass # Stop following elif action == 'unwatch': watchstore.unwatch_project(uid, project_id) goto = req.args.get('goto', req.href('')) return req.redirect(goto)
def filter_stream(self, req, method, filename, stream, data): """ Adds project follower information in project summary block:: Followers: You and 1 other Followers: You and 10 others Followers: 10 """ # Filter only the summary table wiki macro if filename != 'multiproject_summary.html': return stream # Load project and followers info project = Project.get(self.env) watchers, is_watching = self._get_status(req, project.id) # By default show only the number status = tag.span(watchers) # Show link to user preferences if is_watching: status = tag.a('You', href=req.href('../home/prefs/following')) # And others? watchers -= 1 if watchers: status += ngettext(" and %(count)s other", " and %(count)s others", watchers, count=watchers) # Add following information into project summary block trans = Transformer('//div[@class="summary"]/table').append( tag.tr( tag.th('Followers:'), tag.td(status) ) ) return stream | trans
def expand_macro(self, formatter, name, content, args=None): """ Returns the outcome from macro. """ req = formatter.context.req # Check permissions if 'TIMELINE_VIEW' not in req.perm: # Return default content / instructions return tag.div( tag.h2(_('Project team'), **{'class': 'title'}), tag.p( _('Project team cannot be found or no permission to follow it' )), **{'class': 'watch'}) # Load project info from optional project argument. Defaults to current env project = Project.get(self.env) team, members = self._get_team_info(project) # Return rendered HTML with JS attached to it data = { 'project_id': project.id, 'env_name': self.env.project_identifier, 'project_name': self.env.project_identifier, # TODO: redundant 'team': team, 'members': members } # NOTE: Use fragment to not to recreate chrome (add_script does not work) and run post processing manually chrome = Chrome(self.env) stream = chrome.render_template(req, 'multiproject_team.html', data, fragment=True) if req.form_token: stream |= chrome._add_form_token(req.form_token) return stream