Exemplo n.º 1
0
    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
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
    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)
Exemplo n.º 5
0
    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
Exemplo n.º 6
0
    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
Exemplo n.º 7
0
    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