예제 #1
0
 def _format_timeline(self, d, format, dateonly):
     data = Chrome(self.env).populate_data(self.req, {})
     TimelineModule(self.env) \
         .post_process_request(self.req, 'timeline.html', data, None)
     return plaintext(data['pretty_dateinfo'](d,
                                              format=format,
                                              dateonly=dateonly))
    def _format_message(self, user, project, events):
        """
        Create the text body for email
        """
        url_home = self.env.config.get('multiproject', 'url_home').rstrip('/')
        url_service = self.env.config.get('multiproject',
                                          'url_service').rstrip('/')

        # TODO: Move into template
        msg = "Hi %s,\nhere are the latest updates for the project %s that you are following.\n" % (
            user.username, project.project_name)

        for project, event, context in events:
            event_title = plaintext(event['render']('title', context),
                                    keeplinebreaks=False)
            description = self._get_event_description(event, context)
            date = to_web_time(event['date'])
            author = event['author']
            event_url = url_service + str(event['render']('url', context))

            msg += "\n%s\n" % event_title
            if description:
                msg += "%s\n" % description
            msg += "%s by %s\n" % (date, author)
            msg += "Read more about this at %s\n" % event_url

        prefs = url_home + "/prefs/following"
        msg += "\nYou are receiving this e-mail because you subscribed to this project. "
        msg += "You may edit the frequency or stop following this project at %s.\n" % prefs
        return msg
 def _get_event_description(self, event, context):
     if event['kind'] == 'wiki':
         return None
     description = plaintext(event['render']('description', context), keeplinebreaks=False)
     if len(description) > 70:
         description = description[:70] + "..."
     return description
    def _format_message(self, user, project, events):
        """
        Create the text body for email
        """
        url_home = self.env.config.get('multiproject', 'url_home').rstrip('/')
        url_service = self.env.config.get('multiproject', 'url_service').rstrip('/')

        # TODO: Move into template
        msg = "Hi %s,\nhere are the latest updates for the project %s that you are following.\n" % (
        user.username, project.project_name)

        for project, event, context in events:
            event_title = plaintext(event['render']('title', context), keeplinebreaks=False)
            description = self._get_event_description(event, context)
            date = to_web_time(event['date'])
            author = event['author']
            event_url = url_service + str(event['render']('url', context))

            msg += "\n%s\n" % event_title
            if description:
                msg += "%s\n" % description
            msg += "%s by %s\n" % (date, author)
            msg += "Read more about this at %s\n" % event_url

        prefs = url_home + "/prefs/following"
        msg += "\nYou are receiving this e-mail because you subscribed to this project. "
        msg += "You may edit the frequency or stop following this project at %s.\n" % prefs
        return msg
예제 #5
0
    def pre_process_request(self, req, handler):
        """
        Pre-process the request by adding 'Zip Archive' link into alternative format links
        The link is constructed from first and latest revision number, taken from the default
        repository.

        :param Request req: Trac request
        :param object handler: existing handler
        :returns: Handler, modified or not
        """
        # Add link only in /browser or /browser/?rev= pages
        if (self.browser_regx.match(req.path_info)
            and 'BROWSER_VIEW' in req.perm and 'FILE_VIEW' in req.perm):
            # Get default repository and its type
            rm = RepositoryManager(self.env)
            repo = rm.get_repository('')
            repo_type = rm.repository_type

            # Construct the export urls for each format and based on revision info
            latest_rev = plaintext(str(req.args.get('rev', repo.get_youngest_rev())))

            # Use Trac's internal implementation
            if repo_type == 'svn':
                return handler

            # For other types, iterate supported formats
            for format, info in self.formats.items():
                add_link(req, 'alternate', req.href('export/archive', rev=latest_rev, format=format), _(info['desc']),
                    info['mime'], info['ext'])

        return handler
예제 #6
0
    def _parse_heading(self, match, fullmatch, shorten):
        match = match.strip()

        depth = min(len(fullmatch.group('hdepth')), 5)
        anchor = fullmatch.group('hanchor') or ''
        heading_text = match[depth + 1:-depth - 1 - len(anchor)]
        heading = wiki_to_oneliner(self.env, heading_text, self.path,
                                   self.basepath, self.db, False, self.absurls)
        if anchor:
            anchor = anchor[1:]
        else:
            sans_markup = plaintext(heading, keeplinebreaks=False)
            anchor = WikiParser._anchor_re.sub('', sans_markup)
            if not anchor or anchor[0].isdigit() or anchor[0] in '.-':
                # an ID must start with a Name-start character in XHTML
                anchor = 'a' + anchor  # keeping 'a' for backward compat
        i = 1
        anchor_base = anchor
        while anchor in self._anchors:
            anchor = anchor_base + str(i)
            i += 1
        self._anchors[anchor] = True
        if shorten:
            heading = wiki_to_oneliner(self.env, heading_text, self.db, True,
                                       self.absurls)
        return (depth, heading, anchor)
 def _get_event_description(self, event, context):
     if event['kind'] == 'wiki':
         return None
     description = plaintext(event['render']('description', context),
                             keeplinebreaks=False)
     if len(description) > 70:
         description = description[:70] + "..."
     return description
예제 #8
0
    def pre_process_request(self, req, handler):
        """
        Pre-process the request by adding 'Zip Archive' link into alternative format links
        The link is constructed from first and latest revision number, taken from the default
        repository.

        :param Request req: Trac request
        :param object handler: existing handler
        :returns: Handler, modified or not
        """
        # Add link only in /browser or /browser/?rev= pages
        if (self.browser_regx.match(req.path_info)
                and 'BROWSER_VIEW' in req.perm and 'FILE_VIEW' in req.perm):
            # Get default repository and its type
            rm = RepositoryManager(self.env)
            repo = rm.get_repository('')
            repo_type = rm.repository_type

            # Construct the export urls for each format and based on revision info
            try:
                latest_rev = plaintext(
                    str(req.args.get('rev', repo.get_youngest_rev())))
            except:
                pass

            # Use Trac's internal implementation
            if repo_type == 'svn':
                return handler

            # For other types, iterate supported formats
            for format, info in self.formats.items():
                add_link(
                    req, 'alternate',
                    req.href('export/archive', rev=latest_rev, format=format),
                    _(info['desc']), info['mime'], info['ext'])

        return handler
예제 #9
0
 def _format_chrome(self, d, format, dateonly):
     data = Chrome(self.env).populate_data(self.req)
     return plaintext(data['pretty_dateinfo'](d,
                                              format=format,
                                              dateonly=dateonly))
예제 #10
0
파일: web_ui.py 프로젝트: exocad/exotrac
 def _format_timeline(self, d, format, dateonly):
     data = Chrome(self.env).populate_data(self.req, {})
     TimelineModule(self.env).post_process_request(self.req, "timeline.html", data, None)
     return plaintext(data["pretty_dateinfo"](d, format=format, dateonly=dateonly))
예제 #11
0
파일: web_ui.py 프로젝트: exocad/exotrac
 def _format_chrome(self, d, format, dateonly):
     data = Chrome(self.env).populate_data(self.req, {})
     return plaintext(data["pretty_dateinfo"](d, format=format, dateonly=dateonly))
예제 #12
0
    def _do_process(self, req):
        """Handle the redirect from the OpenID server.
        """
        db = self.env.get_db_cnx()
        oidconsumer, session = self._get_consumer(req, db)

        # Ask the library to check the response that the server sent
        # us.  Status is a code indicating the response type. info is
        # either None or a string containing more information about
        # the return type.
        info = oidconsumer.complete(req.args,req.args['openid.return_to'])

        css_class = 'error'
        if info.status == consumer.FAILURE and info.identity_url:
            # In the case of failure, if info is non-None, it is the
            # URL that we were verifying. We include it in the error
            # message to help the user figure out what happened.
            fmt = "Verification of %s failed: %s"
            message = fmt % (cgi.escape(info.identity_url),
                             info.message)
        elif info.status == consumer.SUCCESS:
            # Success means that the transaction completed without
            # error. If info is None, it means that the user cancelled
            # the verification.
            css_class = 'alert'

            # This is a successful verification attempt. If this
            # was a real application, we would do our login,
            # comment posting, etc. here.
            fmt = "You have successfully verified %s as your identity."
            message = fmt % (cgi.escape(info.identity_url),)
            remote_user = info.identity_url

            reg_info = None

            ax_response = ax.FetchResponse.fromSuccessResponse(info)
            if ax_response:
                ax_data = ax_response.getExtensionArgs()
                email = ax_data.get('value.ext0.1', '')
                if email:
                    reg_info = {'email': email, 'fullname': email.split('@', 1)[0].replace('.', ' ').title()}

            if not reg_info:
                response = sreg.SRegResponse.fromSuccessResponse(info)
                if response:
                    reg_info = response.getExtensionArgs()

            if self.strip_protocol:
                remote_user = remote_user[remote_user.find('://')+3:]
            if self.strip_trailing_slash and remote_user[-1] == '/':
                remote_user = remote_user[:-1]
            if info.endpoint.canonicalID:
                # You should authorize i-name users by their canonicalID,
                # rather than their more human-friendly identifiers.  That
                # way their account with you is not compromised if their
                # i-name registration expires and is bought by someone else.
                message += ("  This is an i-name, and its persistent ID is %s"
                            % (cgi.escape(info.endpoint.canonicalID),))
                remote_user = info.endpoint.canonicalID

            allowed = True
            if self.re_white_list:
                self.env.log.debug("Filtering REMOTE_USER '%s' through white-list." % remote_user)
                allowed = False
                for item in self.re_white_list:
                    if not allowed and item.match(remote_user):
                        allowed = True
                        self.env.log.debug("User white-listed.")
            if allowed and self.re_black_list:
                self.env.log.debug("Filtering REMOTE_USER '%s' through black-list." % remote_user)
                for item in self.re_black_list:
                    if item.match(remote_user):
                        allowed = False
                        self.env.log.debug("User black-listed.")

            if allowed and self.check_list:
                params = {self.check_list_key: remote_user}
                if reg_info and reg_info.has_key('email') and len(reg_info['email']) > 0:
                    params['email'] = reg_info['email']
                url = self.check_list + '?' + urllib.urlencode(params)
                self.env.log.debug('OpenID check list URL: %s' % url)
                result = simplejson.load(urllib.urlopen(url))
                if not result[self.check_list_key]:
                    allowed = False
                elif self.check_list_username:
                    new_user = result[self.check_list_username]
                    if new_user:
                        remote_user = new_user

            if allowed:
                cookie = hex_entropy()

                req.outcookie['trac_auth_openid'] = cookie
                req.outcookie['trac_auth_openid']['path'] = req.href()
                req.outcookie['trac_auth_openid']['expires'] = self.trac_auth_expires

                req.session[self.openid_session_identity_url] = info.identity_url
                if reg_info and reg_info.has_key('fullname') and len(reg_info['fullname']) > 0:
                    req.session['name'] = plaintext(reg_info['fullname'], keeplinebreaks=False)
                if reg_info and reg_info.has_key('email') and len(reg_info['email']) > 0:
                    req.session['email'] = plaintext(reg_info['email'], keeplinebreaks=False)

                self._commit_session(session, req) 

                if req.session.has_key('name'):
                    remote_user = req.session['name']
                elif req.session.has_key('email'):
                    remote_user = req.session['email']
                remote_user = plaintext("openid:%s" % (remote_user,), keeplinebreaks=False)

                if self.combined_username and req.session['name']:
                    remote_user = plaintext('%s <%s>' % (req.session['name'], remote_user), keeplinebreaks=False)

                # Check if we generated a colliding remote_user and make the user unique
                collisions = 0
                cremote_user = remote_user
                while True:
                    ds = DetachedSession(self.env, remote_user)
                    if not ds.last_visit:
                        # New session
                        break
                    if not ds.has_key(self.openid_session_identity_url):
                        # Old session, without the iurl set
                        # Save the iurl then (bascially adopt the session)
                        ds[self.openid_session_identity_url] = info.identity_url
                        ds.save()
                        break
                    if ds[self.openid_session_identity_url] == info.identity_url:
                        # No collision
                        break  
                    # We got us a collision
                    # Make the thing unique
                    collisions += 1
                    remote_user = "******" % (cremote_user, collisions)

                req.authname = remote_user

                db = self.env.get_db_cnx()
                cursor = db.cursor()
                cursor.execute("INSERT INTO auth_cookie (cookie,name,ipnr,time) "
                               "VALUES (%s, %s, %s, %s)", (cookie, remote_user,
                               self._get_masked_address(req.remote_addr), int(time.time())))
                db.commit()

                req.redirect(req.session.get('oid.referer') or self.env.abs_href())
            else:
                message = 'You are not allowed here.'
        elif info.status == consumer.CANCEL:
            # cancelled
            message = 'Verification cancelled'
        elif info.status == consumer.SETUP_NEEDED:
            if info.setup_url:
                message = '<a href=%s>Setup needed</a>' % (
                    quoteattr(info.setup_url),)
            else:
                # This means auth didn't succeed, but you're welcome to try
                # non-immediate mode.
                message = 'Setup needed'
        else:
            # Either we don't understand the code or there is no
            # openid_url included with the error. Give a generic
            # failure message. The library should supply debug
            # information in a log.
            message = 'Verification failed.'

        self._commit_session(session, req)

        add_stylesheet(req, 'authopenid/css/openid.css')
        add_script(req, 'authopenid/js/openid-jquery.js')
        return 'openidlogin.html', {
            'images': req.href.chrome('authopenid/images') + '/',
            'action': req.href.openidverify(),
            'message': message,
            'signup': self.signup_link,
            'whatis': self.whatis_link,
            'css_class': css_class,
            'custom_provider_name': self.custom_provider_name,
            'custom_provider_label': self.custom_provider_label,
            'custom_provider_url': self.custom_provider_url,
            'custom_provider_image': self.custom_provider_image,
            }, None
예제 #13
0
    def process_request(self, req):
        """
        Handle the export requests

        :raises: TracError in case of failure
        """
        req.perm.require('BROWSER_VIEW')
        req.perm.require('FILE_VIEW')

        # Get default repository and its type
        rm = RepositoryManager(self.env)
        repo = rm.get_repository('')
        repo_type = rm.repository_type
        svn_path = 'trunk'
        format = plaintext(req.args.get('format', 'zip'))

        # Get revision info. For svn it's in format: <revnum>/<path>
        revision = plaintext(str(req.args.get('rev', repo.get_youngest_rev())))
        if repo_type == 'svn':
            revision = repo.get_youngest_rev()
            svn_path = req.args.get('rev', svn_path)

        # Validate if given revision really exists
        try:
            revision = repo.normalize_rev(revision)
        except NoSuchChangeset:
            raise HTTPNotFound('No such changeset')

        # Validate format
        if format not in self.formats:
            raise TracError('Format is not supported')

        # Load project object based on current environment
        env_name = conf.resolveProjectName(self.env)
        repo_type = self.env.config.get('trac', 'repository_type')
        repo_dir = conf.getEnvironmentVcsPath(env_name)
        project = Project.get(env_name=env_name)

        if repo_type not in conf.supported_scm_systems:
            raise TracError('Non-supported VCS type')

        # Create temporary directory with appropriate subdirectory where to export repository
        tempfd = tempfile.NamedTemporaryFile(delete=False)

        # Dump the repository per type, into defined location
        try:
            if repo_type == 'git':
                # Use short revision format
                revision = revision[:6]
                prefix = '%s-%s' % (env_name, revision[:6])
                self._archive_git(repo_dir, revision, format, tempfd.name, prefix)

            elif repo_type == 'hg':
                # In case of both local:global revision format, use only global
                if ':' in revision:
                    revision = revision.split(':', 1)[1]
                prefix = '%s-%s' % (env_name, revision[:6])
                self._archive_hg(repo_dir, revision, format, tempfd.name, prefix)

            elif repo_type == 'svn':
                assert format == 'zip', 'Only zip format is supported for subversion'

                # Redirect to Trac's internal changeset functionality
                # Example: https://localhost/svnproject/changeset/4/trunk?old_path=%2F&format=zip
                changeset_href = Href('/%s/changeset' % env_name)
                return req.redirect(changeset_href(revision, svn_path, old_path='/', format='zip'))

        # Redirect raises RequestDone: re-raise it
        except RequestDone:
            raise

        except Exception, err:
            self.env.log.exception('Repository dump failed: %s' % err)
            raise TracError('Repository archive failed - please try again later')
예제 #14
0
    def process_request(self, req):

        page_name = req.args.get('page')
        location = req.args.get('location')
        theme = req.args.get('theme', self.default_theme)

        page = WikiPage(self.env, page_name)
        if not page.exists:
            raise TracError('Invalid wiki page "%s"' % page.name)

        page_text = self.fixup_images_re.sub(r'[[Image(wiki:%s:\1)]]'
                                             % page.name, page.text)

        in_section = -1
        text = title = html_title = title_page = handout = ''
        slides = []

        context = Context.from_request(req, page.resource)
        
        for line in page_text.splitlines():
            match = self.heading_re.match(line)
            if match:

                # Insert accumulated text into appropriate location
                if in_section == 1:
                    title_page = format_to_html(self.env, context, text)
                elif in_section == 2:
                    text = self.fixup_re.sub(r'\1', text)
                    slides.append({'body': format_to_html(self.env, context, text),
                                   'handout': format_to_html(self.env, context, handout)})

                if match.lastgroup == 'title':
                    title = match.group(match.lastgroup)
                    html_title = format_to_html(self.env, context, title)
                    title = plaintext(html_title)
                    in_section = 1
                else:
                    in_section = 2
                text = ''

            text += line + '\n'

        if in_section == 1:
            title_page = format_to_html(self.env, context, text)
        elif in_section == 2:
            text = self.fixup_re.sub(r'\1', text)
            slides.append({'body': format_to_html(self.env, context, text),
                           'handout': format_to_html(self.env, context, handout)})

        add_stylesheet(req, 'common/css/code.css')
        add_stylesheet(req, 'common/css/diff.css')
        
        data = {
            'html_title': html_title,
            'location': location,
            'slides': slides,
            'theme': theme,
            'title': title,
            'title_page': title_page
            }

        return 'slideshow.html', data, 'text/html'
예제 #15
0
    def process_request(self, req):
        """
        Handle the export requests

        :raises: TracError in case of failure
        """
        req.perm.require('BROWSER_VIEW')
        req.perm.require('FILE_VIEW')
        repository_name = req.path_info.split("/")[-1]
        # Get default repository and its type
        rm = RepositoryManager(self.env)
        list_repos = rm.get_real_repositories()
        repo = None
        repo_type = None
        for r in list_repos:
            if r.get_base().split("/")[-1].lower() == repository_name:
                repo = r
                break
        repo_type = repo.get_base().split(":")[0]
        svn_path = 'trunk'
        format = plaintext(req.args.get('format', 'zip'))
        conf.log.exception("Repotype at beginning: %s" % repo_type)
        # Get revision info. For svn it's in format: <revnum>/<path>
        revision = plaintext(str(req.args.get('rev', repo.get_youngest_rev())))

        # Validate if given revision really exists
        try:
            revision = repo.normalize_rev(revision)
        except NoSuchChangeset:
            raise HTTPNotFound('No such changeset')

        # Validate format
        if format not in self.formats:
            raise TracError('Format is not supported')

        # Load project object based on current environment
        env_name = conf.resolveProjectName(self.env)
        #repo_type = self.env.config.get('trac', 'repository_type')
        repo_dir = conf.getEnvironmentVcsPath(env_name, repo_type,
                                              repository_name)
        project = Project.get(env_name=env_name)

        if repo_type not in conf.supported_scm_systems:
            raise TracError('Non-supported VCS type')

        # Create temporary directory with appropriate subdirectory where to export repository
        tempfd = tempfile.NamedTemporaryFile(delete=False)

        # Dump the repository per type, into defined location
        conf.log.exception("Repotype: %s, repo_dir: %s" %
                           (repo_type, repo_dir))
        try:
            if repo_type == 'git':
                # Use short revision format
                revision = revision[:6]
                prefix = '%s-%s' % (env_name, revision[:6])
                self._archive_git(repo_dir, revision, format, tempfd.name,
                                  prefix)

            elif repo_type == 'hg':
                # In case of both local:global revision format, use only global
                if ':' in revision:
                    revision = revision.split(':', 1)[1]
                prefix = '%s-%s' % (env_name, revision[:6])
                self._archive_hg(repo_dir, revision, format, tempfd.name,
                                 prefix)

            elif repo_type == 'svn':
                assert format == 'zip', 'Only zip format is supported for subversion'

                # Redirect to Trac's internal changeset functionality
                # Example: https://localhost/svnproject/changeset/4/trunk?old_path=%2F&format=zip
                changeset_href = Href('/%s/changeset' % env_name)
                return req.redirect(
                    changeset_href(revision,
                                   repository_name + "/",
                                   format='zip'))

        # Redirect raises RequestDone: re-raise it
        except RequestDone:
            raise

        except Exception, err:
            self.env.log.exception('Repository dump failed: %s' % err)
            raise TracError(
                'Repository archive failed - please try again later')