Example #1
0
def dispatch_request(path_info, req, env):
    """Main entry point for the Trac web interface."""

    # Re-parse the configuration file if it changed since the last the time it
    # was parsed
    env.config.parse_if_needed()

    base_url = env.config.get('trac', 'base_url')
    if not base_url:
        base_url = absolute_url(req)
    req.base_url = base_url
    req.path_info = to_utf8(path_info)

    env.href = Href(req.cgi_location)
    env.abs_href = Href(req.base_url)

    db = env.get_db_cnx()
    try:
        try:
            dispatcher = RequestDispatcher(env)
            dispatcher.dispatch(req)
        except RequestDone:
            pass
    finally:
        db.close()
def url( req, argument_text, env):
    'can be also done as html-inline-frame or html-object - instead of direct-insert-inline'
    import urllib
    url = argument_text
    try:
        f = urllib.urlopen( url)
    except:
        raise util.TracError( _error_url % locals() )

    text = f.read()
    m = _re_meta_charset.search( text)
    if m:
        charset = m.group(1)
        text = util.to_utf8( text, charset.lower() )

    if 0:
        path,suffix = os.path.splitext( argument_text)
        suffix = suffix[1:]     #skip . from .xxx
        try:
            Format = WikiProcessor( env, suffix)
            html = Format.process( req, text)
            return html, None
        except:
            pass
    return util.Markup( text), None   #raw?
Example #3
0
    def preview_to_hdf(self,
                       req,
                       mimetype,
                       charset,
                       content,
                       filename,
                       detail=None,
                       annotations=None):
        max_preview_size = self.max_preview_size()
        if len(content) >= max_preview_size:
            return {
                'max_file_size_reached': True,
                'max_file_size': max_preview_size
            }

        if not is_binary(content):
            content = to_utf8(content, charset
                              or self.preview_charset(content))
        return {
            'preview':
            self.render(req, mimetype, content, filename, detail, annotations)
        }
Example #4
0
    def _render_diff(self, req, repos, chgset, diff_options):
        """Raw Unified Diff version"""
        req.send_response(200)
        req.send_header('Content-Type', 'text/plain;charset=utf-8')
        req.send_header('Content-Disposition',
                        'filename=Changeset%s.diff' % req.args.get('rev'))
        req.end_headers()

        for path, kind, change, base_path, base_rev in chgset.get_changes():
            if change == Changeset.ADD:
                old_node = None
            else:
                old_node = repos.get_node(base_path or path, base_rev)
            if change == Changeset.DELETE:
                new_node = None
            else:
                new_node = repos.get_node(path, chgset.rev)

            # TODO: Property changes

            # Content changes
            if kind == 'dir':
                continue

            default_charset = self.config.get('trac', 'default_charset')
            new_content = old_content = ''
            new_node_info = old_node_info = ('', '')

            if old_node:
                charset = mimeview.get_charset(old_node.content_type) or \
                          default_charset
                old_content = util.to_utf8(old_node.get_content().read(),
                                           charset)
                old_node_info = (old_node.path, old_node.rev)
            if mimeview.is_binary(old_content):
                continue

            if new_node:
                charset = mimeview.get_charset(new_node.content_type) or \
                          default_charset
                new_content = util.to_utf8(new_node.get_content().read(),
                                           charset)
                new_node_info = (new_node.path, new_node.rev)
            if mimeview.is_binary(new_content):
                continue

            if old_content != new_content:
                context = 3
                for option in diff_options[1]:
                    if option.startswith('-U'):
                        context = int(option[2:])
                        break
                req.write('Index: ' + path + util.CRLF)
                req.write('=' * 67 + util.CRLF)
                req.write('--- %s (revision %s)' % old_node_info + util.CRLF)
                req.write('+++ %s (revision %s)' % new_node_info + util.CRLF)
                for line in unified_diff(old_content.splitlines(),
                                         new_content.splitlines(),
                                         context,
                                         ignore_blank_lines='-B'
                                         in diff_options[1],
                                         ignore_case='-i' in diff_options[1],
                                         ignore_space_changes='-b'
                                         in diff_options[1]):
                    req.write(line + util.CRLF)
Example #5
0
    def _render_html(self, req, repos, chgset, diff_options):
        """HTML version"""
        req.hdf['title'] = '[%s]' % chgset.rev
        req.hdf['changeset'] = {
            'revision':
            chgset.rev,
            'time':
            time.strftime('%c', time.localtime(chgset.date)),
            'author':
            util.escape(chgset.author or 'anonymous'),
            'message':
            wiki_to_html(chgset.message or '--',
                         self.env,
                         req,
                         escape_newlines=True)
        }

        oldest_rev = repos.oldest_rev
        if chgset.rev != oldest_rev:
            add_link(req, 'first', self.env.href.changeset(oldest_rev),
                     'Changeset %s' % oldest_rev)
            previous_rev = repos.previous_rev(chgset.rev)
            add_link(req, 'prev', self.env.href.changeset(previous_rev),
                     'Changeset %s' % previous_rev)
        youngest_rev = repos.youngest_rev
        if str(chgset.rev) != str(youngest_rev):
            next_rev = repos.next_rev(chgset.rev)
            add_link(req, 'next', self.env.href.changeset(next_rev),
                     'Changeset %s' % next_rev)
            add_link(req, 'last', self.env.href.changeset(youngest_rev),
                     'Changeset %s' % youngest_rev)

        edits = []
        idx = 0
        for path, kind, change, base_path, base_rev in chgset.get_changes():
            info = {'change': change}
            if base_path:
                info['path.old'] = base_path
                info['rev.old'] = base_rev
                info['browser_href.old'] = self.env.href.browser(base_path,
                                                                 rev=base_rev)
            if path:
                info['path.new'] = path
                info['rev.new'] = chgset.rev
                info['browser_href.new'] = self.env.href.browser(
                    path, rev=chgset.rev)
            if change in (Changeset.COPY, Changeset.EDIT, Changeset.MOVE):
                edits.append((idx, path, kind, base_path, base_rev))
            req.hdf['changeset.changes.%d' % idx] = info
            idx += 1

        hidden_properties = [
            p.strip() for p in self.config.get('browser', 'hide_properties',
                                               'svk:merge').split(',')
        ]

        for idx, path, kind, base_path, base_rev in edits:
            old_node = repos.get_node(base_path or path, base_rev)
            new_node = repos.get_node(path, chgset.rev)

            # Property changes
            old_props = old_node.get_properties()
            new_props = new_node.get_properties()
            changed_props = {}
            if old_props != new_props:
                for k, v in old_props.items():
                    if not k in new_props:
                        changed_props[k] = {'old': v}
                    elif v != new_props[k]:
                        changed_props[k] = {'old': v, 'new': new_props[k]}
                for k, v in new_props.items():
                    if not k in old_props:
                        changed_props[k] = {'new': v}
                for k in hidden_properties:
                    if k in changed_props:
                        del changed_props[k]
                req.hdf['changeset.changes.%d.props' % idx] = changed_props

            if kind == Node.DIRECTORY:
                continue

            # Content changes
            default_charset = self.config.get('trac', 'default_charset')
            old_content = old_node.get_content().read()
            if mimeview.is_binary(old_content):
                continue
            charset = mimeview.get_charset(old_node.content_type) or \
                      default_charset
            old_content = util.to_utf8(old_content, charset)

            new_content = new_node.get_content().read()
            if mimeview.is_binary(new_content):
                continue
            charset = mimeview.get_charset(new_node.content_type) or \
                      default_charset
            new_content = util.to_utf8(new_content, charset)

            if old_content != new_content:
                context = 3
                for option in diff_options[1]:
                    if option.startswith('-U'):
                        context = int(option[2:])
                        break
                tabwidth = int(
                    self.config.get('diff', 'tab_width',
                                    self.config.get('mimeviewer',
                                                    'tab_width')))
                changes = hdf_diff(old_content.splitlines(),
                                   new_content.splitlines(),
                                   context,
                                   tabwidth,
                                   ignore_blank_lines='-B' in diff_options[1],
                                   ignore_case='-i' in diff_options[1],
                                   ignore_space_changes='-b'
                                   in diff_options[1])
                req.hdf['changeset.changes.%d.diff' % idx] = changes
Example #6
0
def render_downloads_table(env, req):
    """Prepares data for table of downloads."""

    categories_d = {}
    releases_d = {}
    files_d = {}
    categories_obj, categories_list = Categories(env).list
    categories = []
    for category in categories_list:
        category_dict = {
            'id': category.id,
            'name': category.name,
            'notes': category.notes,
            'sort': category.sort,
            'timestamp': category.timestamp
        }
        # Format timestamp
        category_dict['timestamp'] = util.format_datetime(
            category_dict['timestamp'])

        releases_obj, releases_list = category.get_releases()
        releases = []
        for release in releases_list:
            release_dict = {
                'id': release.id,
                'name': release.name,
                'notes': release.notes,
                'sort': release.sort,
                'timestamp': release.timestamp
            }
            # Format timestamp
            release_dict['timestamp'] = util.format_datetime(
                release_dict['timestamp'])

            files_obj, files_list = release.get_files()
            files = []
            for file in files_list:
                file_dict = {
                    'id': file.id,
                    'file': file.file,
                    'name': file.name,
                    'name_disp': file.name_disp,
                    'notes': file.notes,
                    'sort': file.sort,
                    'architecture': file.architecture,
                    'size': '',
                    'timestamp': file.timestamp
                }
                # Format timestamp
                file_dict['timestamp'] = \
                    util.format_datetime(file_dict['timestamp'])
                # Get filesize
                try:
                    size = os.path.getsize(file.file) / 1024.0
                    size = round(size, 2)
                except OSError:
                    env.log.warning("Cannot access file \"" + file.name +\
                                         "\".")
                    size = 0
                size = util.to_utf8(locale.format("%0.2f", size, True))
                file_dict['size'] = size

                files.append(file_dict)
                files_d[file_dict['id']] = file_dict

            release_dict['files'] = files
            releases.append(release_dict)
            releases_d[release_dict['id']] = release_dict

        category_dict['releases'] = releases
        categories.append(category_dict)
        categories_d[category_dict['id']] = category_dict

    req.hdf['categories_list'] = categories
    req.hdf['categories'] = categories_d
    req.hdf['releases'] = releases_d
    req.hdf['files'] = files_d
Example #7
0
def render_downloads_table(env, req, filter=None, f_id=None):
    """Prepares data for table of downloads."""
    
    categories_d = {}
    releases_d = {}
    files_d = {}
    categories_obj, categories_list = Categories(env).list
    categories = []
    for category in categories_list:
        releases_obj, releases_list = category.get_releases()
        releases = []
        
        # Skip unwanted records
        if filter == 'category' and f_id != category.id:
            continue
        elif filter == 'release':
            display = False
            for r in releases_list:
                if r.id == f_id:
                    display = True
            if not display:
                continue
        category_dict = {'id': category.id,
                         'name': category.name,
                         'notes': category.notes,
                         'sort': category.sort,
                         'timestamp': category.timestamp}
        # Format timestamp
        category_dict['timestamp'] = util.format_datetime(category_dict['timestamp'])
        
        for release in releases_list:
            # Skip unwanted records
            if filter == 'release' and f_id != release.id:
                continue
            release_dict = {'id': release.id,
                            'name': release.name,
                            'notes': release.notes,
                            'sort': release.sort,
                            'timestamp': release.timestamp}
            # Format timestamp
            release_dict['timestamp'] = util.format_datetime(release_dict['timestamp'])
            
            
            files_obj, files_list = release.get_files()
            files = []
            for file in files_list:
                file_dict = {'id': file.id,
                              'file': file.file,
                              'name': file.name,
                              'name_disp': file.name_disp,
                              'notes': file.notes,
                              'sort': file.sort,
                              'architecture': file.architecture,
                              'size': '',
                              'timestamp': file.timestamp}
                # Format timestamp
                file_dict['timestamp'] = \
                    util.format_datetime(file_dict['timestamp'])
                # Get filesize
                try:
                    size = os.path.getsize(file.file) / 1024.0
                    size = round(size, 2)
                except OSError:
                    env.log.warning("Cannot access file \"" + file.name +\
                                         "\".")
                    size = 0
                size = util.to_utf8(locale.format("%0.2f", size, True))
                file_dict['size'] = size
                
                files.append(file_dict)
                files_d[file_dict['id']] = file_dict
                
            release_dict['files'] = files
            releases.append(release_dict)
            releases_d[release_dict['id']] = release_dict
            
        category_dict['releases'] = releases
        categories.append(category_dict)
        categories_d[category_dict['id']] = category_dict
        
    req.hdf['categories_list'] = categories
    req.hdf['categories'] = categories_d
    req.hdf['releases'] = releases_d
    req.hdf['files'] = files_d
Example #8
0
    def _render_diff(self, req, repos, chgset, diff_options):
        """Raw Unified Diff version"""
        req.send_response(200)
        req.send_header('Content-Type', 'text/plain;charset=utf-8')
        req.send_header('Content-Disposition', 'inline;'
                        'filename=Changeset%s.diff' % chgset.rev)
        req.end_headers()

        for path, kind, change, base_path, base_rev in chgset.get_changes():
            if change == Changeset.ADD:
                old_node = None
            else:
                old_node = repos.get_node(base_path or path, base_rev)
            if change == Changeset.DELETE:
                new_node = None
            else:
                new_node = repos.get_node(path, chgset.rev)

            # TODO: Property changes

            # Content changes
            if kind == 'dir':
                continue

            default_charset = self.config.get('trac', 'default_charset')
            new_content = old_content = ''
            new_node_info = old_node_info = ('','')

            if old_node:
                charset = mimeview.get_charset(old_node.content_type) or \
                          default_charset
                old_content = util.to_utf8(old_node.get_content().read(),
                                           charset)
                old_node_info = (old_node.path, old_node.rev)
            if mimeview.is_binary(old_content):
                continue

            if new_node:
                charset = mimeview.get_charset(new_node.content_type) or \
                          default_charset
                new_content = util.to_utf8(new_node.get_content().read(),
                                           charset)
                new_node_info = (new_node.path, new_node.rev)
            if mimeview.is_binary(new_content):
                continue

            if old_content != new_content:
                context = 3
                for option in diff_options[1]:
                    if option.startswith('-U'):
                        context = int(option[2:])
                        break
                req.write('Index: ' + path + util.CRLF)
                req.write('=' * 67 + util.CRLF)
                req.write('--- %s (revision %s)' % old_node_info +
                          util.CRLF)
                req.write('+++ %s (revision %s)' % new_node_info +
                          util.CRLF)
                for line in unified_diff(old_content.splitlines(),
                                         new_content.splitlines(), context,
                                         ignore_blank_lines='-B' in diff_options[1],
                                         ignore_case='-i' in diff_options[1],
                                         ignore_space_changes='-b' in diff_options[1]):
                    req.write(line + util.CRLF)
Example #9
0
    def _render_view(self, req, attachment):
        perm_map = {'ticket': 'TICKET_VIEW', 'wiki': 'WIKI_VIEW'}
        req.perm.assert_permission(perm_map[attachment.parent_type])

        fmt = req.args.get('format')
        mimetype = fmt == 'txt' and 'text/plain' or \
                   get_mimetype(attachment.filename) or 'application/octet-stream'

        req.check_modified(attachment.time)

        # Render HTML view
        text, link = self._get_parent_link(attachment)
        add_link(req, 'up', link, text)

        req.hdf['title'] = attachment.title
        req.hdf['attachment'] = attachment_to_hdf(self.env, None, req,
                                                  attachment)
        req.hdf['attachment.parent'] = {
            'type': attachment.parent_type,
            'id': attachment.parent_id,
            'name': text,
            'href': link,
        }

        raw_href = attachment.href(format='raw')
        add_link(req, 'alternate', raw_href, 'Original Format', mimetype)
        req.hdf['attachment.raw_href'] = raw_href

        perm_map = {'ticket': 'TICKET_ADMIN', 'wiki': 'WIKI_DELETE'}
        if req.perm.has_permission(perm_map[attachment.parent_type]):
            req.hdf['attachment.can_delete'] = 1

        self.log.debug("Rendering preview of file %s with mime-type %s" %
                       (attachment.filename, mimetype))
        fd = attachment.open()
        try:
            max_preview_size = int(
                self.config.get('mimeviewer', 'max_preview_size', '262144'))
            data = fd.read(max_preview_size)
            max_size_reached = len(data) == max_preview_size
            charset = detect_unicode(data) or self.config.get(
                'trac', 'default_charset')

            if fmt in ('raw', 'txt'):
                # Send raw file
                req.send_file(attachment.path,
                              mimetype + ';charset=' + charset)
                return

            if not is_binary(data):
                data = util.to_utf8(data, charset)
                add_link(req, 'alternate', attachment.href(format='txt'),
                         'Plain Text', mimetype)
            if max_size_reached:
                req.hdf['attachment.max_file_size_reached'] = 1
                req.hdf['attachment.max_file_size'] = max_preview_size
                vdata = ''
            else:
                mimeview = Mimeview(self.env)
                vdata = mimeview.render(req, mimetype, data,
                                        attachment.filename)
            req.hdf['attachment.preview'] = vdata
        finally:
            fd.close()
Example #10
0
    def _render_file(self, req, repos, node, rev=None):
        req.perm.assert_permission('FILE_VIEW')

        changeset = repos.get_changeset(node.rev)
        req.hdf['file'] = {
            'rev':
            node.rev,
            'changeset_href':
            util.escape(self.env.href.changeset(node.rev)),
            'date':
            time.strftime('%x %X', time.localtime(changeset.date)),
            'age':
            util.pretty_timedelta(changeset.date),
            'author':
            changeset.author or 'anonymous',
            'message':
            wiki_to_html(changeset.message or '--',
                         self.env,
                         req,
                         escape_newlines=True)
        }
        mime_type = node.content_type
        if not mime_type or mime_type == 'application/octet-stream':
            mime_type = get_mimetype(node.name) or mime_type or 'text/plain'

        # We don't have to guess if the charset is specified in the
        # svn:mime-type property
        ctpos = mime_type.find('charset=')
        if ctpos >= 0:
            charset = mime_type[ctpos + 8:]
        else:
            charset = None

        format = req.args.get('format')
        if format in ['raw', 'txt']:
            req.send_response(200)
            req.send_header('Content-Type', format == 'txt' and 'text/plain'
                            or mime_type)
            req.send_header('Content-Length', node.content_length)
            req.send_header('Last-Modified',
                            util.http_date(node.last_modified))
            req.end_headers()

            content = node.get_content()
            while 1:
                chunk = content.read(CHUNK_SIZE)
                if not chunk:
                    raise RequestDone
                req.write(chunk)

        else:
            # Generate HTML preview
            max_preview_size = int(
                self.config.get('mimeviewer', 'max_preview_size', '262144'))
            content = node.get_content().read(max_preview_size)
            max_size_reached = len(content) == max_preview_size
            if not charset:
                charset = detect_unicode(content) or \
                          self.config.get('trac', 'default_charset')
            if not is_binary(content):
                content = util.to_utf8(content, charset)
                if mime_type != 'text/plain':
                    plain_href = self.env.href.browser(node.path,
                                                       rev=rev and node.rev,
                                                       format='txt')
                    add_link(req, 'alternate', plain_href, 'Plain Text',
                             'text/plain')
            if max_size_reached:
                req.hdf['file.max_file_size_reached'] = 1
                req.hdf['file.max_file_size'] = max_preview_size
                preview = ' '
            else:
                preview = Mimeview(self.env).render(req,
                                                    mime_type,
                                                    content,
                                                    node.name,
                                                    node.rev,
                                                    annotations=['lineno'])
            req.hdf['file.preview'] = preview

            raw_href = self.env.href.browser(node.path,
                                             rev=rev and node.rev,
                                             format='raw')
            req.hdf['file.raw_href'] = util.escape(raw_href)
            add_link(req, 'alternate', raw_href, 'Original Format', mime_type)

            add_stylesheet(req, 'common/css/code.css')